65 : fHWndMainWindow(nullptr), fHWndEditor(nullptr),
66 fHWndToolBar(nullptr), fHWndComboBox(nullptr),
67 fHWndComboEditor(nullptr), fHWndHelpTree(nullptr),
68 fHWndStatus(nullptr), menuBar(nullptr),
69 fHelp(false), fHelpChoice(0), fHistoryPos(-1) {
78 INITCOMMONCONTROLSEX commCtrls;
79 commCtrls.dwSize =
sizeof(INITCOMMONCONTROLSEX);
80 commCtrls.dwICC = ICC_BAR_CLASSES | ICC_LISTVIEW_CLASSES;
82 InitCommonControlsEx(&commCtrls);
86 static G4bool Done =
false;
93 wc.hInstance = ::GetModuleHandle(
nullptr);
94 wc.hIcon = LoadIcon(
nullptr, IDI_APPLICATION);
95 wc.hCursor = LoadCursor(
nullptr, IDC_ARROW);
96 wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
100 if (!RegisterClass(&wc)) {
101 MessageBox(
nullptr,
"G4UIWin32: Win32 window registration failed!",
"Error!", MB_ICONEXCLAMATION | MB_OK);
102 G4cout <<
"G4UIWin32: Win32 window registration failed!" <<
G4endl;
112 HMENU hMenu = CreatePopupMenu();
113 AppendMenu(
menuBar, MF_POPUP, (UINT_PTR) hMenu,
"&Geant4");
116 AppendMenu(hMenu, MF_STRING,
ID_OPEN_MACRO,
"&Open macro...");
118 AppendMenu(hMenu, MF_SEPARATOR, -1,
"");
120 AppendMenu(hMenu, MF_SEPARATOR, -1,
"");
121 AppendMenu(hMenu, MF_STRING,
ID_EXIT_APP,
"E&xit");
123 hMenu = CreatePopupMenu();
124 AppendMenu(
menuBar, MF_POPUP, (UINT_PTR) hMenu,
"&View");
129 AppendMenu(hMenu, MF_SEPARATOR, -1,
"");
132 AppendMenu(hMenu, MF_SEPARATOR, -1,
"");
138 hMenu = CreatePopupMenu();
139 AppendMenu(
menuBar, MF_POPUP, (UINT_PTR) hMenu,
"&Zoom");
142 AppendMenu(hMenu, MF_STRING,
ID_ZOOM_IN,
"Zoom &In");
143 AppendMenu(hMenu, MF_STRING,
ID_ZOOM_OUT,
"Zoom &Out");
147 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
148 CW_USEDEFAULT, CW_USEDEFAULT,
149 CW_USEDEFAULT, CW_USEDEFAULT,
151 ::GetModuleHandle(
nullptr),
nullptr);
154 MessageBox(
nullptr,
"Window Creation Failed!",
"Error!", MB_ICONEXCLAMATION | MB_OK);
242 if (a_state ==
"G4_pause> ") {
246 if (a_state ==
"EndOfEvent") {
248 SecondaryLoop(
"End of event, type continue to exit this state");
314 if (!
fHelp)
return false;
332 if (a_name !=
nullptr) {
333 HMENU hMenu = CreatePopupMenu();
334 AppendMenu(
menuBar, MF_POPUP, (UINT_PTR) hMenu, a_label);
346 const char* a_command) {
348 if ((a_menu !=
nullptr) && (a_label !=
nullptr) && (a_command !=
nullptr)) {
369 WPARAM wParam, LPARAM lParam) {
373 if (This !=
nullptr) {
374 if (!This->CreateComponents(aWindow)) {
375 MessageBox(aWindow,
"Could not create components.",
"Error", MB_OK | MB_ICONERROR);
382 auto* This = (
G4UIWin32*) ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
383 if (This !=
nullptr) {
384 if (!This->ResizeComponents(aWindow)) {
385 MessageBox(aWindow,
"Could not resize components.",
"Error", MB_OK | MB_ICONERROR);
392 DestroyWindow(aWindow);
400 auto* This = (
G4UIWin32*) ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
402 SetFocus(This->fHWndComboBox);
406 auto* This = (
G4UIWin32*) ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
407 if (This !=
nullptr) {
408 switch (((LPNMHDR) lParam)->code) {
411 auto lpttt = (LPTOOLTIPTEXT) lParam;
412 lpttt->hinst =
nullptr;
413 UINT idButton = lpttt->hdr.idFrom;
414 lpttt->lpszText = (LPSTR) This->GetToolTips(idButton).c_str();
418 case TVN_GETINFOTIP: {
419 auto pTip = (LPNMTVGETINFOTIP) lParam;
420 pTip->pszText = (LPSTR) This->GetHelpTreeToolTips(pTip->hItem).c_str();
425 auto lpnmh = (LPNMHDR) lParam;
426 auto item = TreeView_GetSelection(lpnmh->hwndFrom);
427 This->HelpTreeDoubleClick(item);
434 auto* This = (
G4UIWin32*) ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
436 if (!This->ProcessDefaultCommands(LOWORD(wParam)))
438 switch (LOWORD(wParam)) {
441 if (HIWORD(wParam) == EN_ERRSPACE || HIWORD(wParam) == EN_MAXTEXT) {
442 G4int bufferSize = SendMessage(This->fHWndEditor, EM_GETLIMITTEXT,
443 (WPARAM) 0, (LPARAM) 0);
446 SendMessage(This->fHWndEditor, EM_SETSEL, (WPARAM) 0, (LPARAM) bufferSize/3);
448 SendMessage(This->fHWndEditor, EM_REPLACESEL, (WPARAM) 0, (LPARAM)
"");
450 SendMessage(This->fHWndEditor, WM_VSCROLL, SB_BOTTOM, NULL);
456 G4String command = This->GetCommand(wParam);
463 return DefWindowProc(aWindow, aMessage, wParam, lParam);
474 HWND parent = GetParent(GetParent(aWindow));
475 auto* This = (
G4UIWin32*) ::GetWindowLongPtr(parent, GWLP_USERDATA);
481 if (This !=
nullptr) {
482 if (This->fHelp)
break;
484 This->ProcessTabKey();
490 This->ProcessEscKey();
495 This->ProcessEnterKey();
500 This->ProcessUpKey();
505 This->ProcessDownKey();
536 G4int statwidths[] = {100, -1};
539 fHWndEditor = CreateWindowEx(WS_EX_CLIENTEDGE,
"EDIT",
"",
540 WS_CHILD | WS_VISIBLE | WS_VSCROLL |
541 WS_HSCROLL | ES_MULTILINE |
542 ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY,
544 GetModuleHandle(
nullptr),
nullptr);
546 MessageBox(aWindow,
"Could not create edit box.",
"Error", MB_OK | MB_ICONERROR);
550 hfDefault = CreateFont(-10, -8, 0, 0, 0,
false, 0, 0, OEM_CHARSET,
551 OUT_RASTER_PRECIS, CLIP_DEFAULT_PRECIS,
552 DEFAULT_QUALITY, FIXED_PITCH,
"System");
553 SendMessage(
fHWndEditor, WM_SETFONT, (WPARAM) hfDefault, MAKELPARAM(
false, 0));
556 SendMessage(
fHWndEditor, EM_SETLIMITTEXT, (WPARAM) 500000, (LPARAM) 0);
559 fHWndToolBar = CreateWindowEx(0, TOOLBARCLASSNAME,
nullptr,
560 WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT |
561 TBSTYLE_TOOLTIPS, 0, 0, 0, 0,
563 GetModuleHandle(
nullptr),
nullptr);
565 MessageBox(aWindow,
"Could not create tool bar.",
"Error", MB_OK | MB_ICONERROR);
568 SendMessage(
fHWndToolBar, TB_BUTTONSTRUCTSIZE, (WPARAM)
sizeof(TBBUTTON), (LPARAM) 0);
571 tbab.hInst = HINST_COMMCTRL;
572 tbab.nID = IDB_STD_SMALL_COLOR;
573 SendMessage(
fHWndToolBar, TB_ADDBITMAP, (WPARAM) 0, (LPARAM) &tbab);
576 tbab.hInst = HINST_COMMCTRL;
577 tbab.nID = IDB_HIST_SMALL_COLOR;
578 SendMessage(
fHWndToolBar, TB_ADDBITMAP, (WPARAM) 0, (LPARAM) &tbab);
581 STD_FIND, STD_FIND, -1,
582 15 + HIST_FORWARD, -1,
584 STD_FILENEW, STD_FILESAVE};
586 TBSTYLE_BUTTON, TBSTYLE_BUTTON, TBSTYLE_SEP,
587 TBSTYLE_BUTTON, TBSTYLE_SEP,
588 TBSTYLE_BUTTON, TBSTYLE_SEP,
589 TBSTYLE_BUTTON, TBSTYLE_BUTTON};
595 ZeroMemory(tbb,
sizeof(tbb));
597 tbb[i].iBitmap = btnBMP[i];
598 tbb[i].fsState = TBSTATE_ENABLED;
599 tbb[i].fsStyle = btnSTL[i];
600 tbb[i].idCommand = btnCMD[i];
603 SendMessage(
fHWndToolBar, TB_ADDBUTTONS,
sizeof(tbb)/
sizeof(TBBUTTON), (LPARAM) &tbb);
607 CBS_DROPDOWN | CBS_HASSTRINGS | WS_CHILD |
608 WS_OVERLAPPED | WS_VISIBLE,
610 GetModuleHandle(
nullptr),
nullptr);
613 SendMessage(
fHWndComboBox, CB_SETCURSEL, (WPARAM) 2, (LPARAM) 0);
626 GetClientRect(aWindow, &rcClient);
629 WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_INFOTIP |
630 TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT,
632 rcClient.right, rcClient.bottom,
634 GetModuleHandle(
nullptr),
nullptr);
643 fHWndStatus = CreateWindowEx(0, STATUSCLASSNAME,
nullptr,
644 WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
647 GetModuleHandle(
nullptr),
nullptr);
649 SendMessage(
fHWndStatus, SB_SETPARTS,
sizeof(statwidths)/
sizeof(
int), (LPARAM) statwidths);
661 G4int iToolHeight, iToolWidth;
667 G4int iComboBoxHeight;
669 G4int iTreeViewHeight, iTreeViewWidth;
670 G4int iEditHeight, iEditWidth;
678 iToolHeight = rcTool.bottom - rcTool.top;
679 iToolWidth = rcTool.right - rcTool.left;
685 iStatusHeight = rcStatus.bottom - rcStatus.top;
691 iComboBoxHeight = rcComboBox.bottom - rcComboBox.top;
694 GetClientRect(aWindow, &rcClient);
696 iTreeViewHeight = rcClient.bottom - iToolHeight - iStatusHeight;
697 iTreeViewWidth = iToolWidth/4;
699 iEditHeight = rcClient.bottom - iToolHeight - iComboBoxHeight - iStatusHeight;
700 iEditWidth = iToolWidth - iTreeViewWidth;
704 iTreeViewWidth, iTreeViewHeight, SWP_NOZORDER);
707 SetWindowPos(
fHWndEditor,
nullptr, iTreeViewWidth, iToolHeight,
708 iEditWidth, iEditHeight, SWP_NOZORDER);
711 SetWindowPos(
fHWndComboBox,
nullptr, iTreeViewWidth, iToolHeight + iEditHeight,
731 const char* d = cmd.data();
749 SendMessage(
fHWndComboBox, CB_SETCURSEL, (WPARAM) (-1), (LPARAM) 0);
760 DWORD dwIndex, numItems;
770 SendMessage(
fHWndComboBox, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
786 if (dwIndex == CB_ERR)
789 if (dwIndex != CB_ERR) {
790 SendMessage(
fHWndComboBox, CB_DELETESTRING, (WPARAM) dwIndex, (LPARAM) 0);
794 numItems = SendMessage(
fHWndComboBox, CB_GETCOUNT, (WPARAM) 0, (LPARAM) 0);
796 SendMessage(
fHWndComboBox, CB_DELETESTRING, (WPARAM) (numItems - 1), (LPARAM) 0);
797 numItems = SendMessage(
fHWndComboBox, CB_GETCOUNT, (WPARAM) 0, (LPARAM) 0);
812 const char* d = command.data();
829 const char* d = command.data();
867 G4String command =
"/vis/viewer/set/style s";
872 G4String command =
"/vis/viewer/set/style w";
877 G4String command =
"/vis/viewer/set/projection o";
882 G4String command =
"/vis/viewer/set/projection p";
887 G4String command =
"/vis/viewer/zoom 1.2";
892 G4String command =
"/vis/viewer/zoom 0.8";
897 G4String command =
"/vis/viewer/set/viewpointThetaPhi 0. 0.";
902 G4String command =
"/vis/viewer/set/viewpointThetaPhi 90. 0.";
907 G4String command =
"/vis/viewer/set/viewpointThetaPhi 0. 90.";
912 G4String command =
"/vis/viewer/set/viewpointThetaPhi 45. -45.";
935 return "Open and execute macro file";
938 return "Save viewer state";
947 return "Beam on (one particle)";
950 return "About G4UIWin32";
970 if (UI ==
nullptr)
return "";
987 if (path)
return path->
GetTitle().data();
1001 G4String str = std::move(a_string);
1002 size_t index = str.find(
"\n", 0);
1003 while (index < str.length()) {
1004 str.replace(index, 2,
"\r\n");
1006 index = str.find(
"\n", index + 2);
1017 G4int l = strlen(item_path);
1032 hFile = CreateFile(fileName, GENERIC_WRITE, 0,
nullptr,
1033 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
nullptr);
1034 if (hFile != INVALID_HANDLE_VALUE) {
1039 if (dwTextLength > 0) {
1041 DWORD dwBufferSize = dwTextLength + 1;
1043 text = (LPSTR) GlobalAlloc(GPTR, dwBufferSize);
1044 if (text !=
nullptr) {
1045 if (GetWindowText(
fHWndEditor, text, dwBufferSize)) {
1048 if (WriteFile(hFile, text, dwTextLength, &dwWritten,
nullptr))
1064 if ((
fHWndEditor !=
nullptr) && (text !=
nullptr) && (text[0] !=
'\0')) {
1069 SendMessage(
fHWndEditor, EM_SETSEL, (WPARAM) ndx, (LPARAM) ndx);
1071 SendMessage(
fHWndEditor, EM_REPLACESEL, (WPARAM) 0, (LPARAM) text);
1073 SendMessage(
fHWndEditor, WM_VSCROLL, SB_BOTTOM, NULL);
1083 char szFileName[MAX_PATH] =
"";
1085 ZeroMemory(&ofn,
sizeof(ofn));
1087 ofn.lStructSize =
sizeof(ofn);
1088 ofn.hwndOwner = aWindow;
1089 ofn.lpstrFilter =
"Macro Files (*.mac)\0*.mac\0All Files (*.*)\0*.*\0";
1090 ofn.lpstrFile = szFileName;
1091 ofn.nMaxFile = MAX_PATH;
1092 ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
1093 ofn.lpstrDefExt =
"mac";
1095 if (GetOpenFileName(&ofn)) {
1099 SendDlgItemMessage(aWindow,
IDC_MAIN_STATUS, SB_SETTEXT, 0, (LPARAM)
"Opened macro...");
1100 SendDlgItemMessage(aWindow,
IDC_MAIN_STATUS, SB_SETTEXT, 1, (LPARAM) szFileName);
1110 char szFileName[MAX_PATH] =
"";
1112 ZeroMemory(&ofn,
sizeof(ofn));
1114 ofn.lStructSize =
sizeof(ofn);
1115 ofn.hwndOwner = aWindow;
1116 ofn.lpstrFilter =
"Macro Files (*.mac)\0*.mac\0All Files (*.*)\0*.*\0";
1117 ofn.lpstrFile = szFileName;
1118 ofn.nMaxFile = MAX_PATH;
1119 ofn.lpstrDefExt =
"mac";
1120 ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
1122 if (GetSaveFileName(&ofn)) {
1126 SendDlgItemMessage(aWindow,
IDC_MAIN_STATUS, SB_SETTEXT, 0, (LPARAM)
"State saved...");
1127 SendDlgItemMessage(aWindow,
IDC_MAIN_STATUS, SB_SETTEXT, 1, (LPARAM) szFileName);
1137 char szFileName[MAX_PATH] =
"";
1139 ZeroMemory(&ofn,
sizeof(ofn));
1141 ofn.lStructSize =
sizeof(ofn);
1142 ofn.hwndOwner = aWindow;
1143 ofn.lpstrFilter =
"Log Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
1144 ofn.lpstrFile = szFileName;
1145 ofn.nMaxFile = MAX_PATH;
1146 ofn.lpstrDefExt =
"txt";
1147 ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
1149 if (GetSaveFileName(&ofn)) {
1151 SendDlgItemMessage(aWindow,
IDC_MAIN_STATUS, SB_SETTEXT, 0, (LPARAM)
"Saved log file...");
1152 SendDlgItemMessage(aWindow,
IDC_MAIN_STATUS, SB_SETTEXT, 1, (LPARAM) szFileName);
1165 if (UI ==
nullptr)
return false;
1170 for (
G4int a = 0; a < treeSize; a++) {
1177 if (newItem ==
nullptr)
1192 if ((aParent !=
nullptr) && (aCommandTree !=
nullptr)) {
1224 TVINSERTSTRUCT tvins;
1225 static auto hPrev = (HTREEITEM) TVI_FIRST;
1227 tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
1230 tvi.pszText = lpszItem;
1231 tvi.cchTextMax =
sizeof(tvi.pszText)/
sizeof(tvi.pszText[0]);
1235 tvi.lParam = (LPARAM) aParent;
1237 tvins.hInsertAfter = hPrev;
1239 tvins.hParent = aParent;
1242 hPrev = (HTREEITEM) SendMessage(
fHWndHelpTree, TVM_INSERTITEM, (WPARAM) 0,
1243 (LPARAM) (LPTVINSERTSTRUCT) &tvins);
1245 if (hPrev ==
nullptr)
1256 G4String str = std::move(commandPath);
1258 if (str.find_last_of(
"/") == (str.size() - 1))
1259 str = str.erase(str.size() - 1, 1);
1261 str = str.erase(0, str.find_last_of(
"/") + 1);
1273 tvitem.mask = TVIF_TEXT;
1274 tvitem.hItem = item;
1275 TCHAR infoTipBuf[1024];
1276 tvitem.pszText = infoTipBuf;
1277 tvitem.cchTextMax =
sizeof(infoTipBuf)/
sizeof(TCHAR);
1279 std::string str =
"";
1280 while (item !=
nullptr) {
1282 str =
"/" + std::string(tvitem.pszText) + str;
1285 tvitem.hItem = item;
1288 auto* result =
new TCHAR[str.size() + 1];
1289 result[str.size()] = 0;
1290 std::copy(str.begin(), str.end(), result);
1301 if (aString ==
nullptr)
return false;
1303 G4long value = strtol(aString, &
s, 10);
1304 if (
s == aString)
return false;
static const G4double pos
static constexpr double s
static G4int actionIdentifier
static WNDPROC origComboEditorWindowProc
static G4bool exitSession
static G4UIsession * tmpSession
static G4bool ConvertStringToInt(const char *, G4int &)
static char mainClassName[]
#define ID_ORIENTATION_YZ
#define ID_ORIENTATION_OBLIQUE
#define IDC_MAIN_TREE_VIEW
#define ID_SAVE_VIEWER_STATE
#define MAX_HISTORY_ITEMS
#define ID_PROJ_ORTHOGRAPHIC
#define ID_ORIENTATION_XY
#define ID_PROJ_PERSPECTIVE
#define ID_ORIENTATION_XZ
#define ID_VIEW_WIREFRAME
G4GLOB_DLL std::ostream G4cout
static G4String GetShortCommandPath(G4String)
G4int ReceiveG4cout(const G4String &) override
HTREEITEM AddItemToHelpTree(LPTSTR, HTREEITEM=TVI_ROOT)
G4bool GetHelpChoice(G4int &) override
G4UIsession * SessionStart() override
std::vector< G4String > fHistory
G4bool ProcessDefaultCommands(G4int)
static LRESULT CALLBACK MainWindowProc(HWND, UINT, WPARAM, LPARAM)
void ExitHelp() const override
std::map< G4int, G4String, std::less< G4int > > commands
void CreateHelpTree(HTREEITEM, G4UIcommandTree *)
void SecondaryLoop(const G4String &)
G4VInteractorManager * interactorManager
void AddMenu(const char *, const char *) override
static LRESULT CALLBACK ComboEditorWindowProc(HWND, UINT, WPARAM, LPARAM)
void PauseSessionStart(const G4String &) override
G4String GetHelpTreeToolTips(HTREEITEM)
LPSTR GetItemPath(HTREEITEM)
G4bool SaveLogFile(LPCTSTR)
G4bool InitHelpTreeItems()
G4bool ResizeComponents(HWND)
static G4String GetToolTips(G4int)
G4String GetCommand(G4int)
void AddButton(const char *, const char *, const char *) override
static G4String ConvertNewLines(G4String)
G4int ReceiveG4cerr(const G4String &) override
void Prompt(const G4String &)
G4bool CreateComponents(HWND)
void HelpTreeDoubleClick(HTREEITEM)
G4int GetCommandEntry() const
G4UIcommand * GetCommand(G4int i)
const G4String & GetPathName() const
G4int GetTreeEntry() const
G4UIcommandTree * GetTree(G4int i)
G4UIcommandTree * FindCommandTree(const char *commandPath)
const G4String GetTitle() const
G4UIcommand * FindPath(const char *commandPath) const
const G4String & GetGuidanceLine(G4int i) const
const G4String & GetCommandPath() const
void SetCoutDestination(G4UIsession *const value)
G4UIcommandTree * GetTree() const
static G4UImanager * GetUIpointer()
void SetSession(G4UIsession *const value)
void SetG4UIWindow(G4UIsession *const value)
G4String Complete(const G4String &)
void ApplyShellCommand(const G4String &, G4bool &, G4bool &)
void AddInteractor(G4String, G4Interactor)
G4Interactor GetInteractor(G4String)
void EnableSecondaryLoop()
void DisableSecondaryLoop()
virtual void * GetEvent()=0
void DispatchEvent(void *)
static G4Win32 * getInstance()
void copy(G4double dst[], const G4double src[], size_t size=G4FieldTrack::ncompSVEC)