1 | // |
---|
2 | // ******************************************************************** |
---|
3 | // * License and Disclaimer * |
---|
4 | // * * |
---|
5 | // * The Geant4 software is copyright of the Copyright Holders of * |
---|
6 | // * the Geant4 Collaboration. It is provided under the terms and * |
---|
7 | // * conditions of the Geant4 Software License, included in the file * |
---|
8 | // * LICENSE and available at http://cern.ch/geant4/license . These * |
---|
9 | // * include a list of copyright holders. * |
---|
10 | // * * |
---|
11 | // * Neither the authors of this software system, nor their employing * |
---|
12 | // * institutes,nor the agencies providing financial support for this * |
---|
13 | // * work make any representation or warranty, express or implied, * |
---|
14 | // * regarding this software system or assume any liability for its * |
---|
15 | // * use. Please see the license in the file LICENSE and URL above * |
---|
16 | // * for the full disclaimer and the limitation of liability. * |
---|
17 | // * * |
---|
18 | // * This code implementation is the result of the scientific and * |
---|
19 | // * technical work of the GEANT4 collaboration. * |
---|
20 | // * By using, copying, modifying or distributing the software (or * |
---|
21 | // * any work based on the software) you agree to acknowledge its * |
---|
22 | // * use in resulting scientific publications, and indicate your * |
---|
23 | // * acceptance of all terms of the Geant4 Software license. * |
---|
24 | // ******************************************************************** |
---|
25 | // |
---|
26 | // |
---|
27 | // $Id: G4UIWin32.cc,v 1.13 2006/06/29 19:09:45 gunter Exp $ |
---|
28 | // GEANT4 tag $Name: geant4-09-00-ref-01 $ |
---|
29 | // |
---|
30 | // G.Barrand |
---|
31 | |
---|
32 | //#define DEBUG |
---|
33 | |
---|
34 | #ifdef G4UI_BUILD_WIN32_SESSION |
---|
35 | |
---|
36 | // this : |
---|
37 | #include "G4UIWin32.hh" |
---|
38 | |
---|
39 | #include <string.h> |
---|
40 | |
---|
41 | #include <windows.h> |
---|
42 | #include <windowsx.h> |
---|
43 | #include <wingdi.h> |
---|
44 | |
---|
45 | #include <strstream> |
---|
46 | |
---|
47 | #include "G4UImanager.hh" |
---|
48 | #include "G4StateManager.hh" |
---|
49 | #include "G4UIcommandTree.hh" |
---|
50 | #include "G4UIcommandStatus.hh" |
---|
51 | #include "G4Win32.hh" |
---|
52 | |
---|
53 | #define TEXT_MAX_LINES 300 |
---|
54 | |
---|
55 | class TextBuffer |
---|
56 | { |
---|
57 | public: |
---|
58 | TextBuffer(); |
---|
59 | ~TextBuffer(); |
---|
60 | |
---|
61 | int GetNumberOfLines () { return linei;} |
---|
62 | void SetHeightOfPage (int a_height) { heightOfPage = a_height; } |
---|
63 | void SetEndOfPage (int a_value); |
---|
64 | int GetEndOfPage () { return endOfPage; } |
---|
65 | |
---|
66 | void IncrementEndOfPage (); |
---|
67 | void DecrementEndOfPage (); |
---|
68 | void JumpDownEndOfPage (); |
---|
69 | void JumpUpEndOfPage (); |
---|
70 | G4bool AppendString (char* a_string); |
---|
71 | void Draw (HDC a_hdc,RECT* a_rect); |
---|
72 | |
---|
73 | private: |
---|
74 | G4String* lines; |
---|
75 | int linen; |
---|
76 | int linei; |
---|
77 | int endOfPage,heightOfPage; |
---|
78 | char spaces[256]; |
---|
79 | }; |
---|
80 | |
---|
81 | TextBuffer::TextBuffer() |
---|
82 | : linei(0),linen(TEXT_MAX_LINES),endOfPage(0),heightOfPage(12) |
---|
83 | { |
---|
84 | lines = new G4String[linen]; |
---|
85 | for(int count=0;count<256;count++) spaces[count] = ' '; |
---|
86 | } |
---|
87 | |
---|
88 | TextBuffer::~TextBuffer() |
---|
89 | { |
---|
90 | delete [] lines; |
---|
91 | } |
---|
92 | |
---|
93 | void TextBuffer::SetEndOfPage (int a_value) |
---|
94 | { |
---|
95 | if( (a_value<0) || (a_value>=linei)) { |
---|
96 | endOfPage = linei-1; |
---|
97 | } else { |
---|
98 | endOfPage = a_value; |
---|
99 | } |
---|
100 | } |
---|
101 | |
---|
102 | void TextBuffer::IncrementEndOfPage () |
---|
103 | { |
---|
104 | endOfPage++; |
---|
105 | if(endOfPage>=linei) endOfPage = linei-1; |
---|
106 | } |
---|
107 | |
---|
108 | void TextBuffer::DecrementEndOfPage () |
---|
109 | { |
---|
110 | endOfPage--; |
---|
111 | if(endOfPage<0) endOfPage = 0; |
---|
112 | } |
---|
113 | |
---|
114 | void TextBuffer::JumpDownEndOfPage () |
---|
115 | { |
---|
116 | endOfPage += heightOfPage; |
---|
117 | if(endOfPage>=linei) endOfPage = linei-1; |
---|
118 | } |
---|
119 | |
---|
120 | void TextBuffer::JumpUpEndOfPage () |
---|
121 | { |
---|
122 | endOfPage -= heightOfPage; |
---|
123 | if(endOfPage<0) endOfPage = 0; |
---|
124 | } |
---|
125 | |
---|
126 | G4bool TextBuffer::AppendString (char* a_string) |
---|
127 | { |
---|
128 | G4bool value = false; |
---|
129 | if( (a_string==NULL) || (a_string[0]=='\0') ) return value; |
---|
130 | int length = strlen(a_string); |
---|
131 | if(a_string[length-1]=='\n') { |
---|
132 | lines[linei] += a_string; |
---|
133 | lines[linei] = lines[linei].strip(G4String::trailing,'\n'); |
---|
134 | linei++; |
---|
135 | value = true; |
---|
136 | } else { |
---|
137 | lines[linei] += a_string; |
---|
138 | } |
---|
139 | if(linei>=linen) { |
---|
140 | for(int count=0;count<linen;count++) { |
---|
141 | lines[count] = ""; |
---|
142 | } |
---|
143 | linei = 0; |
---|
144 | } |
---|
145 | if(value==true) endOfPage = linei-1; |
---|
146 | return value; |
---|
147 | } |
---|
148 | |
---|
149 | void TextBuffer::Draw (HDC a_hdc,RECT* a_rect) |
---|
150 | { |
---|
151 | TEXTMETRIC tm; |
---|
152 | GetTextMetrics (a_hdc,&tm); |
---|
153 | short charWidth = (short)tm.tmAveCharWidth; |
---|
154 | short charHeight = (short)(tm.tmHeight + tm.tmExternalLeading); |
---|
155 | for(int row=0;row<heightOfPage;row++) { |
---|
156 | int rowi = endOfPage - row; |
---|
157 | short y = (short)(a_rect->bottom - charHeight * (row + 1)); |
---|
158 | if((rowi>=0)&&(rowi<linei)) { |
---|
159 | TextOut (a_hdc,0,y,(char*)spaces,256); //Clear text background first. |
---|
160 | const char* string = lines[rowi].data(); |
---|
161 | if(string!=NULL) { |
---|
162 | TextOut (a_hdc,0,y,(char*)string,strlen((char*)string)); |
---|
163 | } |
---|
164 | } |
---|
165 | } |
---|
166 | } |
---|
167 | |
---|
168 | /***************************************************************************/ |
---|
169 | static char mainClassName[] = "G4UIWin32"; |
---|
170 | static char textClassName[] = "G4UIWin32/Text"; |
---|
171 | static G4bool exitSession = true; |
---|
172 | static G4bool exitPause = true; |
---|
173 | static G4bool exitHelp = true; |
---|
174 | static G4UIsession* tmpSession = NULL; |
---|
175 | |
---|
176 | static WNDPROC oldEditWindowProc; |
---|
177 | static G4bool ConvertStringToInt(const char*,int&); |
---|
178 | |
---|
179 | static int actionIdentifier = 0; |
---|
180 | |
---|
181 | /***************************************************************************/ |
---|
182 | G4UIWin32::G4UIWin32 ( |
---|
183 | ) |
---|
184 | :mainWindow(NULL) |
---|
185 | ,textWindow(NULL) |
---|
186 | ,editWindow(NULL) |
---|
187 | ,menuBar(NULL) |
---|
188 | ,textBuffer(NULL) |
---|
189 | ,textCols(80) |
---|
190 | ,textRows(12) |
---|
191 | ,fHelp(false) |
---|
192 | ,fHelpChoice(0) |
---|
193 | ,fHistoryPos(-1) |
---|
194 | /***************************************************************************/ |
---|
195 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
196 | { |
---|
197 | G4UImanager* UI = G4UImanager::GetUIpointer(); |
---|
198 | if(UI!=NULL) UI->SetSession(this); |
---|
199 | |
---|
200 | interactorManager = G4Win32::getInstance (); |
---|
201 | static G4bool Done = FALSE; |
---|
202 | if(Done==FALSE) { |
---|
203 | WNDCLASS wc; |
---|
204 | wc.style = CS_HREDRAW | CS_VREDRAW; |
---|
205 | wc.lpfnWndProc = (WNDPROC)G4UIWin32::MainWindowProc; |
---|
206 | wc.cbClsExtra = 0; |
---|
207 | wc.cbWndExtra = 0; |
---|
208 | wc.hInstance = ::GetModuleHandle(NULL); |
---|
209 | wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); |
---|
210 | wc.hCursor = LoadCursor(NULL,IDC_ARROW); |
---|
211 | wc.hbrBackground = GetStockBrush(WHITE_BRUSH); |
---|
212 | wc.lpszMenuName = mainClassName; |
---|
213 | wc.lpszClassName = mainClassName; |
---|
214 | ::RegisterClass (&wc); |
---|
215 | |
---|
216 | wc.style = CS_HREDRAW | CS_VREDRAW; |
---|
217 | wc.lpfnWndProc = (WNDPROC)G4UIWin32::TextWindowProc; |
---|
218 | wc.cbClsExtra = 0; |
---|
219 | wc.cbWndExtra = 0; |
---|
220 | wc.hInstance = ::GetModuleHandle(NULL); |
---|
221 | wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); |
---|
222 | wc.hCursor = LoadCursor(NULL,IDC_ARROW); |
---|
223 | wc.hbrBackground = GetStockBrush(WHITE_BRUSH); |
---|
224 | wc.lpszMenuName = textClassName; |
---|
225 | wc.lpszClassName = textClassName; |
---|
226 | ::RegisterClass (&wc); |
---|
227 | Done = TRUE; |
---|
228 | } |
---|
229 | |
---|
230 | menuBar = CreateMenu(); |
---|
231 | defaultMenu = CreatePopupMenu(); |
---|
232 | AppendMenu(menuBar,MF_POPUP,(UINT)defaultMenu,"Geant4"); |
---|
233 | |
---|
234 | textBuffer = new TextBuffer(); |
---|
235 | |
---|
236 | tmpSession = this; |
---|
237 | mainWindow = ::CreateWindow(mainClassName,mainClassName, |
---|
238 | WS_OVERLAPPEDWINDOW, |
---|
239 | CW_USEDEFAULT,CW_USEDEFAULT, |
---|
240 | 0,0, |
---|
241 | NULL,menuBar, |
---|
242 | ::GetModuleHandle(NULL), |
---|
243 | NULL); |
---|
244 | tmpSession = NULL; |
---|
245 | ::SetWindowLong(mainWindow,GWL_USERDATA,LONG(this)); |
---|
246 | |
---|
247 | ::SetForegroundWindow(mainWindow); |
---|
248 | ::ShowWindow(mainWindow,SW_SHOWDEFAULT); |
---|
249 | ::UpdateWindow(mainWindow); |
---|
250 | |
---|
251 | if(UI!=NULL) UI->SetCoutDestination(this); |
---|
252 | } |
---|
253 | /***************************************************************************/ |
---|
254 | G4UIWin32::~G4UIWin32 ( |
---|
255 | ) |
---|
256 | /***************************************************************************/ |
---|
257 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
258 | { |
---|
259 | G4UImanager* UI = G4UImanager::GetUIpointer(); |
---|
260 | if(UI!=NULL) { |
---|
261 | UI->SetSession(NULL); |
---|
262 | UI->SetCoutDestination(NULL); |
---|
263 | } |
---|
264 | delete textBuffer; |
---|
265 | if(textWindow!=NULL) ::SetWindowLong(textWindow,GWL_USERDATA,LONG(NULL)); |
---|
266 | if(mainWindow!=NULL) { |
---|
267 | ::SetWindowLong(mainWindow,GWL_USERDATA,LONG(NULL)); |
---|
268 | ::DestroyWindow(mainWindow); |
---|
269 | } |
---|
270 | } |
---|
271 | /***************************************************************************/ |
---|
272 | G4UIsession* G4UIWin32::SessionStart ( |
---|
273 | ) |
---|
274 | /***************************************************************************/ |
---|
275 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
276 | { |
---|
277 | if(interactorManager==NULL) return this; |
---|
278 | Prompt ("session"); |
---|
279 | exitSession = false; |
---|
280 | interactorManager->DisableSecondaryLoop (); |
---|
281 | void* event; |
---|
282 | while((event = interactorManager->GetEvent())!=NULL) { |
---|
283 | interactorManager->DispatchEvent(event); |
---|
284 | if(exitSession==true) break; |
---|
285 | } |
---|
286 | interactorManager->EnableSecondaryLoop (); |
---|
287 | return this; |
---|
288 | } |
---|
289 | /***************************************************************************/ |
---|
290 | void G4UIWin32::Prompt ( |
---|
291 | G4String a_prompt |
---|
292 | ) |
---|
293 | /***************************************************************************/ |
---|
294 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
295 | { |
---|
296 | } |
---|
297 | /***************************************************************************/ |
---|
298 | void G4UIWin32::SessionTerminate ( |
---|
299 | ) |
---|
300 | /***************************************************************************/ |
---|
301 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
302 | { |
---|
303 | } |
---|
304 | /***************************************************************************/ |
---|
305 | void G4UIWin32::PauseSessionStart ( |
---|
306 | G4String a_state |
---|
307 | ) |
---|
308 | /***************************************************************************/ |
---|
309 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
310 | { |
---|
311 | if(a_state=="G4_pause> ") { |
---|
312 | SecondaryLoop ("Pause, type continue to exit this state"); |
---|
313 | } |
---|
314 | |
---|
315 | if(a_state=="EndOfEvent") { |
---|
316 | // Picking with feed back in event data Done here !!! |
---|
317 | SecondaryLoop ("End of event, type continue to exit this state"); |
---|
318 | } |
---|
319 | } |
---|
320 | /***************************************************************************/ |
---|
321 | void G4UIWin32::SecondaryLoop ( |
---|
322 | G4String a_prompt |
---|
323 | ) |
---|
324 | /***************************************************************************/ |
---|
325 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
326 | { |
---|
327 | if(interactorManager==NULL) return; |
---|
328 | Prompt(a_prompt); |
---|
329 | exitPause = false; |
---|
330 | void* event; |
---|
331 | while((event = interactorManager->GetEvent())!=NULL) { |
---|
332 | interactorManager->DispatchEvent(event); |
---|
333 | if(exitPause==true) break; |
---|
334 | } |
---|
335 | Prompt("session"); |
---|
336 | } |
---|
337 | /***************************************************************************/ |
---|
338 | G4int G4UIWin32::ReceiveG4cout ( |
---|
339 | G4String a_string |
---|
340 | ) |
---|
341 | /***************************************************************************/ |
---|
342 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
343 | { |
---|
344 | TextAppendString((char*)a_string.data()); |
---|
345 | return 0; |
---|
346 | } |
---|
347 | /***************************************************************************/ |
---|
348 | G4int G4UIWin32::ReceiveG4cerr ( |
---|
349 | G4String a_string |
---|
350 | ) |
---|
351 | /***************************************************************************/ |
---|
352 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
353 | { |
---|
354 | TextAppendString((char*)a_string.data()); |
---|
355 | return 0; |
---|
356 | } |
---|
357 | /***************************************************************************/ |
---|
358 | G4bool G4UIWin32::GetHelpChoice( |
---|
359 | G4int& aInt |
---|
360 | ) |
---|
361 | /***************************************************************************/ |
---|
362 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
363 | { |
---|
364 | fHelp = true; |
---|
365 | // |
---|
366 | if(interactorManager==NULL) return false; |
---|
367 | Prompt("Help"); |
---|
368 | exitHelp = false; |
---|
369 | void* event; |
---|
370 | while((event = interactorManager->GetEvent())!=NULL) { |
---|
371 | interactorManager->DispatchEvent(event); |
---|
372 | if(exitHelp==true) break; |
---|
373 | } |
---|
374 | Prompt("session"); |
---|
375 | // |
---|
376 | if(fHelp==false) return false; |
---|
377 | aInt = fHelpChoice; |
---|
378 | fHelp = false; |
---|
379 | return true; |
---|
380 | } |
---|
381 | /***************************************************************************/ |
---|
382 | void G4UIWin32::ExitHelp( |
---|
383 | ) |
---|
384 | /***************************************************************************/ |
---|
385 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
386 | { |
---|
387 | } |
---|
388 | /***************************************************************************/ |
---|
389 | void G4UIWin32::AddMenu ( |
---|
390 | const char* a_name |
---|
391 | ,const char* a_label |
---|
392 | ) |
---|
393 | /***************************************************************************/ |
---|
394 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
395 | { |
---|
396 | if(a_name==NULL) return; |
---|
397 | if(defaultMenu!=NULL) { |
---|
398 | DeleteMenu (menuBar,0,MF_BYPOSITION); |
---|
399 | defaultMenu = NULL; |
---|
400 | } |
---|
401 | HMENU hMenu = CreatePopupMenu(); |
---|
402 | AppendMenu(menuBar,MF_POPUP,(UINT)hMenu,a_label); |
---|
403 | AddInteractor(a_name,(G4Interactor)hMenu); |
---|
404 | DrawMenuBar(mainWindow); |
---|
405 | } |
---|
406 | /***************************************************************************/ |
---|
407 | void G4UIWin32::AddButton ( |
---|
408 | const char* a_menu |
---|
409 | ,const char* a_label |
---|
410 | ,const char* a_command |
---|
411 | ) |
---|
412 | /***************************************************************************/ |
---|
413 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
414 | { |
---|
415 | if(a_menu==NULL) return; |
---|
416 | if(a_label==NULL) return; |
---|
417 | if(a_command==NULL) return; |
---|
418 | HMENU hMenu = (HMENU)GetInteractor(a_menu); |
---|
419 | actionIdentifier++; |
---|
420 | commands[actionIdentifier] = a_command; |
---|
421 | AppendMenu (hMenu,MF_STRING,actionIdentifier,a_label); |
---|
422 | } |
---|
423 | /***************************************************************************/ |
---|
424 | G4String G4UIWin32::GetCommand ( |
---|
425 | int a_id |
---|
426 | ) |
---|
427 | /***************************************************************************/ |
---|
428 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
429 | { |
---|
430 | return commands[a_id]; |
---|
431 | } |
---|
432 | /***************************************************************************/ |
---|
433 | /***************************************************************************/ |
---|
434 | /***************************************************************************/ |
---|
435 | LRESULT CALLBACK G4UIWin32::MainWindowProc ( |
---|
436 | HWND a_window |
---|
437 | ,UINT a_message |
---|
438 | ,WPARAM a_wParam |
---|
439 | ,LPARAM a_lParam |
---|
440 | ) |
---|
441 | /***************************************************************************/ |
---|
442 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
443 | { |
---|
444 | static short charWidth,charHeight; |
---|
445 | |
---|
446 | switch (a_message) { |
---|
447 | case WM_CREATE:{ |
---|
448 | HDC hdc; |
---|
449 | TEXTMETRIC tm; |
---|
450 | RECT rect; |
---|
451 | GetWindowRect (a_window,&rect); |
---|
452 | |
---|
453 | hdc = GetDC (a_window); |
---|
454 | GetTextMetrics (hdc,&tm); |
---|
455 | charWidth = (short)tm.tmAveCharWidth; |
---|
456 | charHeight = (short)(tm.tmHeight + tm.tmExternalLeading); |
---|
457 | ReleaseDC (a_window,hdc); |
---|
458 | |
---|
459 | G4UIWin32* This = (G4UIWin32*)tmpSession; |
---|
460 | if(This!=NULL) { |
---|
461 | This->textWindow = CreateWindow (textClassName,NULL, |
---|
462 | WS_CHILD | WS_VISIBLE | WS_VSCROLL, |
---|
463 | 0,0, |
---|
464 | This->textCols * charWidth, |
---|
465 | This->textRows * charHeight, |
---|
466 | a_window,NULL, |
---|
467 | GetWindowInstance(a_window), |
---|
468 | NULL); |
---|
469 | ::SetWindowLong (This->textWindow,GWL_USERDATA,LONG(This)); |
---|
470 | |
---|
471 | This->editWindow = CreateWindow ("edit",NULL, |
---|
472 | WS_CHILD | WS_VISIBLE | WS_BORDER, |
---|
473 | 0,This->textRows * charHeight, |
---|
474 | This->textCols * charWidth,charHeight, |
---|
475 | a_window,(HMENU)1, |
---|
476 | GetWindowInstance(a_window), |
---|
477 | NULL); |
---|
478 | oldEditWindowProc = (WNDPROC)GetWindowLong(This->editWindow,GWL_WNDPROC); |
---|
479 | SetWindowLong (This->editWindow,GWL_WNDPROC,(LONG)EditWindowProc); |
---|
480 | |
---|
481 | MoveWindow (a_window, |
---|
482 | rect.left,rect.top, |
---|
483 | 2 * GetSystemMetrics(SM_CXFRAME) + |
---|
484 | This->textCols * charWidth, |
---|
485 | GetSystemMetrics(SM_CYCAPTION) + |
---|
486 | 2 * GetSystemMetrics(SM_CYFRAME) + |
---|
487 | This->textRows * charHeight + charHeight, |
---|
488 | TRUE); |
---|
489 | } |
---|
490 | }return 0; |
---|
491 | case WM_SIZE:{ |
---|
492 | G4UIWin32* This = (G4UIWin32*)::GetWindowLong(a_window,GWL_USERDATA); |
---|
493 | if(This!=NULL) { |
---|
494 | // Client size : |
---|
495 | int width = LOWORD(a_lParam); |
---|
496 | int height = HIWORD(a_lParam); |
---|
497 | int editHeight = /*2 * GetSystemMetrics(SM_CYBORDER) + */ charHeight; |
---|
498 | MoveWindow (This->textWindow, |
---|
499 | 0,0, |
---|
500 | width,height - editHeight, |
---|
501 | FALSE); |
---|
502 | MoveWindow (This->editWindow, |
---|
503 | 0,height - editHeight, |
---|
504 | width,charHeight, |
---|
505 | FALSE); |
---|
506 | ((TextBuffer*)This->textBuffer)->SetHeightOfPage(height/charHeight); |
---|
507 | } |
---|
508 | }return 0; |
---|
509 | case WM_SETFOCUS:{ |
---|
510 | G4UIWin32* This = (G4UIWin32*)::GetWindowLong(a_window,GWL_USERDATA); |
---|
511 | if(This!=NULL) SetFocus (This->editWindow); |
---|
512 | }return 0; |
---|
513 | case WM_COMMAND:{ |
---|
514 | G4UIWin32* This = (G4UIWin32*)::GetWindowLong(a_window,GWL_USERDATA); |
---|
515 | if(This!=NULL) { |
---|
516 | if(This->fHelp==false) { |
---|
517 | G4String command = This->GetCommand(a_wParam); |
---|
518 | This->ApplyShellCommand (command,exitSession,exitPause); |
---|
519 | } |
---|
520 | } |
---|
521 | }return 0; |
---|
522 | case WM_DESTROY: |
---|
523 | PostQuitMessage(0); |
---|
524 | return 0; |
---|
525 | } |
---|
526 | return (DefWindowProc(a_window,a_message,a_wParam,a_lParam)); |
---|
527 | } |
---|
528 | /***************************************************************************/ |
---|
529 | LRESULT CALLBACK G4UIWin32::TextWindowProc ( |
---|
530 | HWND a_window |
---|
531 | ,UINT a_message |
---|
532 | ,WPARAM a_wParam |
---|
533 | ,LPARAM a_lParam |
---|
534 | ) |
---|
535 | /***************************************************************************/ |
---|
536 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
537 | { |
---|
538 | switch (a_message) { |
---|
539 | case WM_PAINT:{ |
---|
540 | G4UIWin32* This = (G4UIWin32*)::GetWindowLong(a_window,GWL_USERDATA); |
---|
541 | if(This!=NULL) { |
---|
542 | TextBuffer* textBuffer = (TextBuffer*)This->textBuffer; |
---|
543 | RECT rect; |
---|
544 | GetClientRect (a_window,&rect); |
---|
545 | PAINTSTRUCT ps; |
---|
546 | HDC hdc = BeginPaint(a_window,&ps); |
---|
547 | textBuffer->Draw(hdc,&rect); |
---|
548 | EndPaint(a_window,&ps); |
---|
549 | } |
---|
550 | }return 0; |
---|
551 | case WM_VSCROLL:{ |
---|
552 | G4UIWin32* This = (G4UIWin32*)::GetWindowLong(a_window,GWL_USERDATA); |
---|
553 | if(This!=NULL) { |
---|
554 | TextBuffer* textBuffer = (TextBuffer*)This->textBuffer; |
---|
555 | int what = LOWORD(a_wParam); |
---|
556 | switch(what) { |
---|
557 | case SB_LINEUP: |
---|
558 | textBuffer->DecrementEndOfPage(); |
---|
559 | break; |
---|
560 | case SB_LINEDOWN: |
---|
561 | textBuffer->IncrementEndOfPage(); |
---|
562 | break; |
---|
563 | case SB_PAGEUP: |
---|
564 | textBuffer->JumpUpEndOfPage(); |
---|
565 | break; |
---|
566 | case SB_PAGEDOWN: |
---|
567 | textBuffer->JumpDownEndOfPage(); |
---|
568 | break; |
---|
569 | case SB_THUMBPOSITION: |
---|
570 | case SB_THUMBTRACK: |
---|
571 | textBuffer->SetEndOfPage(HIWORD(a_wParam)); |
---|
572 | break; |
---|
573 | default: |
---|
574 | return 0; |
---|
575 | } |
---|
576 | int eop = textBuffer->GetEndOfPage(); |
---|
577 | SetScrollPos(a_window,SB_VERT,eop,TRUE); |
---|
578 | InvalidateRect(a_window,NULL,TRUE); |
---|
579 | }}return 0; |
---|
580 | case WM_DESTROY: |
---|
581 | PostQuitMessage(0); |
---|
582 | return 0; |
---|
583 | } |
---|
584 | return (DefWindowProc(a_window,a_message,a_wParam,a_lParam)); |
---|
585 | } |
---|
586 | /***************************************************************************/ |
---|
587 | LRESULT CALLBACK G4UIWin32::EditWindowProc ( |
---|
588 | HWND a_window |
---|
589 | ,UINT a_message |
---|
590 | ,WPARAM a_wParam |
---|
591 | ,LPARAM a_lParam |
---|
592 | ) |
---|
593 | /***************************************************************************/ |
---|
594 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
595 | { |
---|
596 | switch (a_message) { |
---|
597 | case WM_KEYDOWN: |
---|
598 | switch(a_wParam){ |
---|
599 | case VK_RETURN:{ |
---|
600 | G4UIWin32* This = (G4UIWin32*)::GetWindowLong( |
---|
601 | GetParent(a_window),GWL_USERDATA); |
---|
602 | char buffer[128]; |
---|
603 | GetWindowText (a_window,buffer,128); |
---|
604 | G4String command (buffer); |
---|
605 | //SetWindowText (a_window,""); |
---|
606 | Edit_SetText(a_window,""); |
---|
607 | Edit_SetSel(a_window,0,0); |
---|
608 | |
---|
609 | if(This!=NULL) { |
---|
610 | if(This->fHelp==true) { |
---|
611 | exitHelp = true; |
---|
612 | This->fHelp = ConvertStringToInt(command.data(),This->fHelpChoice); |
---|
613 | } else { |
---|
614 | This->fHistory.push_back(command); |
---|
615 | This->fHistoryPos = -1; |
---|
616 | This->ApplyShellCommand (command,exitSession,exitPause); |
---|
617 | } |
---|
618 | } |
---|
619 | |
---|
620 | }break; |
---|
621 | case VK_TAB:{ |
---|
622 | G4UIWin32* This = (G4UIWin32*)::GetWindowLong( |
---|
623 | GetParent(a_window),GWL_USERDATA); |
---|
624 | if( (This!=NULL) && (This->fHelp==true) ) break; |
---|
625 | char buffer[128]; |
---|
626 | Edit_GetText(a_window,buffer,128); |
---|
627 | |
---|
628 | G4String command(buffer); |
---|
629 | |
---|
630 | if(This!=NULL) { |
---|
631 | G4String cmd = This->Complete(command); |
---|
632 | const char* d = cmd.data(); |
---|
633 | int l = strlen(d); |
---|
634 | Edit_SetText(a_window,d); |
---|
635 | Edit_SetSel(a_window,l,l); |
---|
636 | } |
---|
637 | |
---|
638 | }break; |
---|
639 | case VK_UP:{ |
---|
640 | G4UIWin32* This = (G4UIWin32*)::GetWindowLong( |
---|
641 | GetParent(a_window),GWL_USERDATA); |
---|
642 | if(This!=NULL) { |
---|
643 | int pos = This->fHistoryPos== -1 ? |
---|
644 | This->fHistory.size()-1 : This->fHistoryPos-1; |
---|
645 | if((pos>=0)&&(pos<(int)This->fHistory.size())) { |
---|
646 | G4String command = This->fHistory[pos]; |
---|
647 | const char* d = command.data(); |
---|
648 | int l = strlen(d); |
---|
649 | Edit_SetText(a_window,d); |
---|
650 | Edit_SetSel(a_window,l,l); |
---|
651 | // |
---|
652 | This->fHistoryPos = pos; |
---|
653 | } |
---|
654 | } |
---|
655 | }return 0; //Do not jump into oldEditProc. |
---|
656 | case VK_DOWN:{ |
---|
657 | G4UIWin32* This = (G4UIWin32*)::GetWindowLong( |
---|
658 | GetParent(a_window),GWL_USERDATA); |
---|
659 | if(This!=NULL) { |
---|
660 | int pos = This->fHistoryPos + 1; |
---|
661 | if((pos>=0)&&(pos<(int)This->fHistory.size())) { |
---|
662 | G4String command = This->fHistory[pos]; |
---|
663 | const char* d = command.data(); |
---|
664 | int l = strlen(d); |
---|
665 | Edit_SetText(a_window,d); |
---|
666 | Edit_SetSel(a_window,l,l); |
---|
667 | // |
---|
668 | This->fHistoryPos = pos; |
---|
669 | } else if(pos>=(int)This->fHistory.size()) { |
---|
670 | Edit_SetText(a_window,""); |
---|
671 | Edit_SetSel(a_window,0,0); |
---|
672 | // |
---|
673 | This->fHistoryPos = -1; |
---|
674 | } |
---|
675 | } |
---|
676 | }return 0; //Do not jump into oldEditProc. |
---|
677 | } |
---|
678 | } |
---|
679 | return CallWindowProc(oldEditWindowProc, |
---|
680 | a_window,a_message, |
---|
681 | a_wParam,a_lParam); |
---|
682 | } |
---|
683 | /***************************************************************************/ |
---|
684 | void G4UIWin32::TextAppendString ( |
---|
685 | char* a_string |
---|
686 | ) |
---|
687 | /***************************************************************************/ |
---|
688 | /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
---|
689 | { |
---|
690 | if( (a_string==NULL) || (a_string[0]=='\0') ) return; |
---|
691 | if(textWindow==NULL) return; |
---|
692 | if(((TextBuffer*)textBuffer)->AppendString(a_string)==true) { |
---|
693 | // The appending triggers and end of line, and then updates window : |
---|
694 | RECT rect; |
---|
695 | GetClientRect(textWindow,&rect); |
---|
696 | InvalidateRect(textWindow,NULL,TRUE); //To erase background. |
---|
697 | HDC hdc = GetDC(textWindow); |
---|
698 | ((TextBuffer*)textBuffer)->Draw(hdc,&rect); |
---|
699 | ReleaseDC (textWindow,hdc); |
---|
700 | int linen = ((TextBuffer*)textBuffer)->GetNumberOfLines(); |
---|
701 | SetScrollRange(textWindow,SB_VERT,0,linen-1,TRUE); |
---|
702 | SetScrollPos(textWindow,SB_VERT,linen-1,TRUE); |
---|
703 | } |
---|
704 | } |
---|
705 | ////////////////////////////////////////////////////////////////////////////// |
---|
706 | G4bool ConvertStringToInt( |
---|
707 | const char* aString |
---|
708 | ,int& aInt |
---|
709 | ) |
---|
710 | ////////////////////////////////////////////////////////////////////////////// |
---|
711 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!// |
---|
712 | { |
---|
713 | aInt = 0; |
---|
714 | if(aString==NULL) return false; |
---|
715 | char* s; |
---|
716 | long value = strtol(aString,&s,10); |
---|
717 | if(s==aString) return false; |
---|
718 | aInt = value; |
---|
719 | return true; |
---|
720 | } |
---|
721 | |
---|
722 | |
---|
723 | #endif |
---|