File: UTILS\U_WINDOW.CPP
1 //#############################################################################
2 // //
3 // U_WINDOW.CPP //
4 // //
5 // Subsystem : Fenster-Templates: modale und modeless Dialog; MDI-Fenster //
6 // Benutung durch andere Subsysteme erforderlich: JA //
7 // Deklaration: U_WINDOW.H //
8 //---------------------------------------------------------------------------//
9 // Autor(en): Thomas Kullmann, Günther Reinecker //
10 // Quelle: verschoben aus DLG_TPL.CPP //
11 // Stand: 10.04.2002 //
12 // //
13 //#############################################################################
14
15 #include "utils\u_window.h" // SCHNITTSTELLE für diese Datei
16 #include "internls\evrythng.h" // für GermanVersion
17
18 //#############################################################################
19 // sprachspezifische Konstanten
20 //#############################################################################
21
22 #ifdef GermanVersion
23 const char _MSGTITLE[]= "Meldung";
24 const char _NONUMBER[]= "Der eingebene Wert ist keine Zahl!\nBitte prüfen Sie Ihre Eingabe.";
25 const char _NOWINDOW[]= "Fenster kann nicht erzeugt werden!";
26 const char _ERRTITLE[]= "FEHLER";
32 #endif
33
34 //#############################################################################
35 // global
36 //#############################################################################
37
38 BOOL _CURVECLASS WINAPI SetActivateHotKey ( HWND aWnd, const char aKey, const BOOL aShift, const BOOL aCtrl, const BOOL aAlt, const BOOL aExtended )
39 {
40 // Taste | HEX
41 //----------+------
42 // Shift | 1
43 // Ctrl | 2
44 // Alt | 4
45 // Extended | 8
46 // Ctrl+Alt= sum(Ctrl, Alt)= 0x6
47 //
48 // 'P' | 50
49 // Ctrl+Alt+'P'= concat('6', '50')= 0x650
50 UINT modifier= 0;
51 if ( aShift )
52 modifier += HOTKEYF_SHIFT;
53 if ( aCtrl )
54 modifier += HOTKEYF_CONTROL;
55 if ( aAlt )
56 modifier += HOTKEYF_ALT;
57 if ( aExtended )
58 modifier += HOTKEYF_EXT;
59 // Keycode berechnen und registrieren
60 WPARAM keycode= modifier;
61 keycode *= 256; // shift modifier to the upper byte
62 keycode += aKey;
63 UINT iSetResult= SendMessage( aWnd, WM_SETHOTKEY, keycode, 0 );
64 switch ( iSetResult )
65 {
66 case 2: // ERFOLG: Tastenkombination bereits angemeldet
67 return TRUE;
68
69 case 1: // ERFOLG
70 return TRUE;
71
72 case 0: // ungültiges HotKey-Fenster
73 return FALSE;
74
75 case -1: // ungültige Tastenkombination
76 return FALSE;
77
78 default: // unbekannter Fehler
79 return FALSE;
80 }
81 }
82
83 //#############################################################################
84 // THotKey
85 //#############################################################################
86
87 THotKey::THotKey ( HWND aWindow, const char aKey, const BOOL aShift, const BOOL aCtrl, const BOOL aAlt, const BOOL aWin ) : m_Cmd( -1)
88 {
89 m_Window= aWindow;
90 UINT modifier= CalcModifier ( aShift, aCtrl, aAlt, aWin );
91 m_KeyCode= CalcKeyCode ( aKey, aShift, aCtrl, aAlt, aWin );
92 // eindeutigen Namen ermitteln
93 char buf[51];
94 sprintf(buf, "HOTKEYATOM%d%d", m_Window, m_KeyCode);
95 m_Atom= GlobalAddAtom(buf);
96 // registrieren
97 if ( m_Atom )
98 m_Registered= RegisterHotKey( m_Window, m_Atom, modifier, aKey );
99 else
100 m_Registered= FALSE;
101 }
102 //-----------------------------------------------------------------------------
103
104 THotKey::~THotKey ( void )
105 {
106 if ( (m_Atom) && (m_Registered) )
107 {
108 UnregisterHotKey( m_Window, m_Atom );
109 }
110 if ( m_Atom )
111 {
112 GlobalDeleteAtom( m_Atom );
113 m_Atom= 0;
114 }
115 }
116 //-----------------------------------------------------------------------------
117
118 UINT THotKey::CalcModifier ( const BOOL aShift, const BOOL aCtrl, const BOOL aAlt, const BOOL aWin )
119 {
120 UINT result= 0;
121 if ( aShift )
122 result += MOD_SHIFT;
123 if ( aCtrl )
124 result += MOD_CONTROL;
125 if ( aAlt )
126 result += MOD_ALT;
127 if ( aWin )
128 result += MOD_WIN;
129 return result;
130 }
131 //-----------------------------------------------------------------------------
132
133 LPARAM THotKey::CalcKeyCode ( const char aKey, const BOOL aShift, const BOOL aCtrl, const BOOL aAlt, const BOOL aWin )
134 {
135 LPARAM result= aKey;
136 result *= long(65536); // shift key to the upper word
137 result += CalcModifier( aShift, aCtrl, aAlt, aWin );
138 return result;
139 }
140
141 //*****************************************************************************
142 // Accessormethode(n)
143 //*****************************************************************************
144
145 BOOL THotKey::IsEqual ( LPARAM lParam ) const
146 {
147 return ( (IsRegistered()) && (m_KeyCode == lParam) );
148 };
149 //-----------------------------------------------------------------------------
150
151 BOOL THotKey::IsRegistered ( void ) const
152 {
153 return ( m_Atom);
154 };
155
156 //#############################################################################
157 // TBasicWindow
158 //#############################################################################
159
160 TIndList TBasicWindow::s_WindowList(true, true, false, true);
161 TBasicWindow *TBasicWindow::s_WaitingWindow= 0; // es gibt kein angemeldetes Fenster
162
163 //*****************************************************************************
164 // Konstruktor-Destruktor
165 //*****************************************************************************
166
167 TBasicWindow::TBasicWindow ( HINSTANCE aInstance )
168 {
169 m_Window= 0; // kein Fensterhandle
170 m_Instance= aInstance;
171 }
172 //-----------------------------------------------------------------------------
173
174 TBasicWindow::~TBasicWindow ( void )
175 {
176 for (UINT i= 0; i < m_HotKeys.size(); i++ )
177 _FREEOBJ(m_HotKeys[i]); // Tastenkombinationen unregistrieren und Objekte freigeben
178 m_HotKeys.resize(0); // Borland 5.02 unterützt kein clear, obwohl von STL vorgeschrieben!
179
180 UnregisterWindow(); // Fensterregistrierung beenden (spätestens jetzt wird das Fenster nicht mehr angezeigt)
181 };
182 //*****************************************************************************
183
184 char *TBasicWindow::LoadString ( const int aStrTbleId ) const
185 {
186 BOOL bValid;
187 return LoadString( aStrTbleId, bValid );
188 }
189 //-----------------------------------------------------------------------------
190
191 char *TBasicWindow::LoadString ( const int aStrTbleId, BOOL &aValid ) const
192 {
193 int actLen= 50;
194 while (1) {
195 char *MsgString= new char[actLen+1];
196 int len= ::LoadString( GetInstance(), aStrTbleId, MsgString, actLen );
197 if ( len>=actLen-1 && actLen<512 ) { // in jedem Durchlauf 50 Zeichen mehr Platz gewähren
198 _FREELIST(MsgString);
199 actLen+= 50;
200 continue;
201 }
202 if ( len ) { // Eintrag existiert
203 aValid= TRUE;
204 char *result= new char[ strlen(MsgString)+1 ]; // + Nullterminierung
205 strcpy(result, MsgString);
206 _FREELIST(MsgString);
207 return result;
208 } else { // Eintrag ist nicht vorhanden
209 _FREELIST(MsgString);
210 aValid= FALSE;
211 const char prae[]= "RESID-FEHLER!!! Für RessourcenId %d ist kein StringTable-Eintrag verfügbar.";
212 char *buf= new char[ strlen(prae)+_MAXLENDOUBLE+1 ];
213 sprintf(buf, prae, aStrTbleId);
214 TraceErr(buf);
215 _FREEOBJ(buf);
216
217 char *result= new char[ 0+1 ]; // nur Nullterminierung
218 strcpy(result, "");
219 return result;
220 }
221 }
222 }
223 //*****************************************************************************
224
225 char *TBasicWindow::GetWindowTxt ( HWND aWindow )
226 {
227 int actLen= 50;
228 while (1) {
229 char *MsgString= new char[actLen+1];
230 int len= ::GetWindowText( aWindow, MsgString, actLen );
231 if ( len>=actLen-1 && actLen<512 ) { // in jedem Durchlauf 50 Zeichen mehr Platz gewähren
232 _FREELIST(MsgString);
233 actLen+= 50;
234 continue;
235 }
236 if ( len ) { // Fenster existiert
237 char *result= new char[ strlen(MsgString)+1 ]; // + Nullterminierung
238 strcpy(result, MsgString);
239 _FREELIST(MsgString);
240 return result;
241 } else { // Fenster ist nicht vorhanden oder hat keinen Titel
242 _FREELIST(MsgString);
243 const char prae[]= "ohne Titel";
244 char *result= new char[ strlen(prae)+1 ];
245 strcpy(result, prae);
246 return result;
247 }
248 }
249 }
250 //-----------------------------------------------------------------------------
251
252 char *TBasicWindow::GetWindowTxt()
253 {
254 return GetWindowTxt(m_Window);
255 }
256 //*****************************************************************************
257
258 int TBasicWindow::MessageBox(LPCSTR aText, LPCSTR aCap, UINT uType) const
259 {
260 char *buf= new char[ max(strlen(_MSGTITLE), strlen(aCap)) ];
261 if ( strlen(aCap)==0 ) strcpy(buf, _MSGTITLE);
262 else strcpy(buf, aCap);
263 if ( uType==0 ) uType= MB_OK;
264 return ::MessageBox(GetHandle(), aText, buf, uType);
265 };
266 //-----------------------------------------------------------------------------
267
268 int TBasicWindow::MessageBox(const int aStrTbleId, LPCSTR aCap, UINT uType) const
269 {
270 char *MsgString= LoadString( aStrTbleId ); // ggf. ""
271 int result= MessageBox(MsgString, aCap, uType);
272 _FREELIST(MsgString);
273 return result;
274 }
275 //-----------------------------------------------------------------------------
276
277 int TBasicWindow::MessageBox(LPCSTR aText, const int aStrTbleId, UINT uType) const
278 {
279 char *MsgString= LoadString( aStrTbleId ); // ggf. ""
280 int result= MessageBox(aText, MsgString, uType);
281 _FREELIST(MsgString);
282 return result;
283 }
284 //-----------------------------------------------------------------------------
285
286 int TBasicWindow::MessageBox(const int aStrTbleId, const int aStrTbleId2, UINT uType) const
287 {
288 char *MsgString= LoadString( aStrTbleId2 ); // ggf. ""
289 int result= MessageBox(aStrTbleId, MsgString, uType);
290 _FREELIST(MsgString);
291 return result;
292 }
293 //-----------------------------------------------------------------------------
294
295 HCURSOR TBasicWindow::SetDefaultCursor(LPCTSTR aName) {
296 return SetCursor( LoadCursor(NULL, aName) );
297 }
298
299 //*****************************************************************************
300 // Liste der registrierten Fenster; Zuordnung HWND <--> Fensterobjekt
301 //*****************************************************************************
302
303 void TBasicWindow::RegisterWindow ( HWND aWindow )
304 {
305 if ( s_WaitingWindow == this )
306 s_WaitingWindow= 0; // hier registrieren wir das Fenster, es ist also kein unregistriertes Fenster mehr
307
308 // sind wir schon registriert?
309 if ( !s_WindowList.Append(this) )
310 return; // wir sind schon in der Liste (Abbruch)
311
312 m_Window= aWindow;
313 }
314 //-----------------------------------------------------------------------------
315
316 void TBasicWindow::UnregisterWindow ( void )
317 {
318 if ( s_WaitingWindow == this )
319 s_WaitingWindow= 0; // falls das Fenster gar KEINE Windowsbotschaft erhalten haben sollte: jedenfalls wartet es nicht länger auf ein Handle
320
321 // aus der Liste der registrierten Fenster entfernen
322 s_WindowList.RemoveData(this);
323 m_Window= 0; // kein Fensterhandle mehr
324 }
325 //-----------------------------------------------------------------------------
326
327 TBasicWindow *TBasicWindow::Handle2Object ( HWND aWindow )
328 {
329 // Objekt aus der Liste der registrierten Fenster ermitteln; damit endlich auch Zugriff auf Member
330 for (TIndex i= 0; i<s_WindowList.GetCount(); i++) {
331 TBasicWindow *result= (TBasicWindow *)s_WindowList[i];
332 if ( result && result->m_Window==aWindow )
333 return result; // gefunden :-)
334 }
335 return 0; // nicht gefunden
336 }
337 //-----------------------------------------------------------------------------
338
339 LRESULT CALLBACK TBasicWindow::EventHandlerEx ( HWND aWindow, UINT aId, WPARAM wParam, LPARAM lParam, BOOL &aValid )
340 {
341 aValid= FALSE;
342 // Objekt aus der Liste der registrierten Fenster ermitteln; damit endlich auch Zugriff auf Member
343 TBasicWindow *self= Handle2Object(aWindow);
344
345 // Wenn das Fensterhandle nicht in der Liste der registrierten Fenster ist, prüfe ob sich ein
346 // unregistriertes Fenster angemeldet hat und auf seine erste Windowsbotschaft (sein Handle) wartet.
347 // Wenn JA, registriere dieses Fenster und hebe den Wartezustand auf
348 if ( (!self) && (s_WaitingWindow) )
349 { // Problem besteht weil das zuletzt anzuzeigende, modale Dialogfenster NUR durch WM_INITDIALOG sein Handle erfahren kann - DialogBoxParam() gibt kein Handle zurück
350 self= s_WaitingWindow; // Botschaft war für's angemeldete Fenster
351 s_WaitingWindow->RegisterWindow( aWindow ); // Fenster registrieren und Wartezustand aufheben (s_WaitingWindow= 0)
352 };
353 if ( !self ) { // weder registrierets noch angemeldetes Fenster: Botschaft nicht verarbeitet
354 if ( aId==WM_GETTEXT ) return FALSE; // diese Nachricht wurde von uns und GetWindowTxt ausgelöst; keine Meldung ausgeben !!!
355
356 char *txt= GetWindowTxt(aWindow);
357 const char prae[]= "Unbekannte Windows-Botschaft mit ID= %d, WPARAM= %d, LPARAM= %d, HWND= %d (%s) !";
358 char *buf= new char[ strlen(prae) + 4*_MAXLENDOUBLE + strlen(txt) + 1 ];
359 sprintf(buf, prae, aId, wParam, lParam, aWindow, txt);
360 _FREELIST(txt);
361 TraceErr(buf);
362 _FREELIST(buf);
363 return FALSE;
364 }
365
366 // Botschaft nur an registrierte oder angemeldete Fenster weiterleiten
367 aValid= TRUE;
368 return self->OnEvent( aWindow, aId, wParam, lParam );
369 }
370 //-----------------------------------------------------------------------------
371
372 LRESULT CALLBACK TBasicWindow::EventHandler ( HWND aWindow, UINT aId, WPARAM wParam, LPARAM lParam )
373 {
374 BOOL bValid= TRUE;
375 return EventHandlerEx(aWindow, aId, wParam, lParam, bValid);
376 }
377
378 //*****************************************************************************
379 // Tastenkombinationen
380 //*****************************************************************************
381 BOOL TBasicWindow::SetActivateHotKey ( const char aKey, const BOOL aShift, const BOOL aCtrl, const BOOL aAlt, const BOOL aExtended )
382 {
383 return ::SetActivateHotKey ( GetHandle(), aKey, aShift, aCtrl, aAlt, aExtended );
384 }
385 //-----------------------------------------------------------------------------
386
387 BOOL TBasicWindow::AddHotKey ( const char aKey, const BOOL aShift, const BOOL aCtrl, const BOOL aAlt, const BOOL aWin )
388 {
389 THotKey *ht= new THotKey( GetHandle(), aKey, aShift, aCtrl, aAlt, aWin );
390 m_HotKeys.push_back( ht );
391 return ht->IsRegistered();
392 }
393 //-----------------------------------------------------------------------------
394
395 UINT TBasicWindow::LoadHotKeys ( HACCEL aAccel )
396 {
397 // Accelerator aus Ressourcen laden und in <table> kopieren
398 UINT count= CopyAcceleratorTable( aAccel, NULL, 0); // Anzahl der Tastenkombinatioen ermitteln
399 ACCEL *table= new ACCEL[ count ]; // Tabelle der Tastenkombinationen erstellen
400 CopyAcceleratorTable( aAccel, table, count ); // Tabelle mit Tastenkombinationen füllen
401
402 // Tastenkombinationen registrieren; Informationen aus der "Tabelle mit Tastenkombinationen" entnehmen
403 for (UINT i= 0; i < count; i++)
404 {
405 THotKey *ht= new THotKey( GetHandle(), (char)table[i].key, table[i].fVirt & FSHIFT, table[i].fVirt & FCONTROL, table[i].fVirt & FALT, FALSE ); // Windows-Taste wird in Ressourcen nicht unterstützt !
406 ht->m_Cmd= table[i].cmd;
407 m_HotKeys.push_back( ht );
408 }
409
410 _FREELIST(table); // "Tabelle mit Tastenkombinationen" freigeben
411 return count;
412 }
413 //-----------------------------------------------------------------------------
414
415 BOOL TBasicWindow::IsHotKey ( LPARAM lParam, const char aKey, const BOOL aShift, const BOOL aCtrl, const BOOL aAlt, const BOOL aWin )
416 {
417 return ( lParam == THotKey::CalcKeyCode( aKey, aShift, aCtrl, aAlt, aWin ) );
418 }
419
420 //#############################################################################
421 // TBasicDialog
422 //#############################################################################
423
424 TBasicDialog::TBasicDialog ( const char *aResName, HINSTANCE aInstance ) : TBasicWindow(aInstance), m_ResName(0)
425 {
426 m_ResName= new char[ strlen(aResName) + 1 ]; // + Nullterminierung
427 strcpy( m_ResName, aResName );
428 }
429 //-----------------------------------------------------------------------------
430
431 TBasicDialog::~TBasicDialog ( void )
432 {
433 _FREELIST(m_ResName);
434 }
435
436 //*****************************************************************************
437 // EREIGNISSE
438 //*****************************************************************************
439
440 LRESULT TBasicDialog::OnEvent ( HWND aWindow, UINT aId, WPARAM wParam, LPARAM lParam )
441 {
442 BOOL result= TRUE; // Botschaft durch HANDLE_MSG verarbeitet
443 switch ( aId )
444 {
445 // Standardereignisse
446 HANDLE_MSG( aWindow, WM_COMMAND, Dlg_OnCommand );
447 HANDLE_MSG( aWindow, WM_INITDIALOG, Dlg_OnInit );
448 HANDLE_MSG( aWindow, WM_HSCROLL, Dlg_OnHScrollBar );
449 HANDLE_MSG( aWindow, WM_VSCROLL, Dlg_OnVScrollBar );
450 HANDLE_MSG( aWindow, WM_TIMER, Dlg_OnTimer );
451
452 // Mausereignisse (Klier)
453 HANDLE_MSG( aWindow, WM_LBUTTONUP, Dlg_OnLButtonUp );
454 HANDLE_MSG( aWindow, WM_LBUTTONDOWN, Dlg_OnLButtonDown );
455 HANDLE_MSG( aWindow, WM_RBUTTONDOWN, Dlg_OnRButtonDown );
456 HANDLE_MSG( aWindow, WM_MOUSEMOVE, Dlg_OnMouseMove );
457 HANDLE_MSG( aWindow, WM_MOUSEACTIVATE, Dlg_OnMouseActivate );
458
459 // Rest
460 HANDLE_MSG( aWindow, WM_DESTROY, Dlg_OnDestroy );
461 HANDLE_MSG( aWindow, WM_SETFOCUS, Dlg_OnSetFocus );
462
463 case WM_HOTKEY:
464 {
465 for (UINT i= 0; i < m_HotKeys.size(); i++ )
466 if ( GetFocus() )
467 { // nur wenn Fenster aktiv, sonst fangen wir die Tastenkombinationen auch wenn unsere Anwendung inaktiv ist!!!
468 THotKey *hk= m_HotKeys[i];
469 if ( (hk) && (hk->IsEqual(lParam)) )
470 {
471 Dlg_OnCommand( GetHandle(), hk->m_Cmd, 0, 0 );
472 return TRUE; // Botschaft verarbeitet
473 }
474 } // sonst kann man in einer überschiebenen Methoden selbst auf WM_HOTKEY reagieren
475 break;
476 }
477
478 // Systemcommand (klier 24.08.02)
479 case WM_SYSCOMMAND:
480 result= Dlg_OnSysCommand( aWindow, wParam, lParam );
481 break;
482
483 // Systemfarben haben sich geändert
484 case WM_SYSCOLORCHANGE:
485 //Datum: 27.07.2002 ! Ctl3dColorChange( );
486 break;
487
488 // Tastatur
489 case WM_CHAR: // WM_KEYDOWN-Ergebnis bereits übersetzt in WM_CHAR (Taste mit ASCII-Code wurde gedrückt)
490 result= Dlg_OnChar( aWindow, wParam, lParam );
491 break;
492
493 //10.07.2003 klier
494 // Auf Änderungen an TabCtrl und ListView kann reagiert werden!
495 case WM_NOTIFY:
496 Dlg_OnNotify( aWindow, aId, wParam, lParam );
497 return TRUE;
498 break;
499
500 default:
501 result= TBasicWindow::OnEvent(aWindow, aId, wParam, lParam);
502 } // switch
503 return result;
504 }
505 //-----------------------------------------------------------------------------
506
507 BOOL TBasicDialog::Dlg_OnChar ( HWND, WPARAM aCharCode, LPARAM )
508 {
509 if ( aCharCode == VK_ESCAPE )
510 { // ESC-Taste gedrückt und losgelassen
511 // Datum: 27.07.2002 if(1 < (int)GET_WM_COMMAND_HWND(wParam,lParam))
512 Interrupt( );
513 }
514 return TRUE; // Botschaft verarbeitet
515 }
516
517 //*****************************************************************************
518 // Verwaltung des Inhalts von Steuerelementen
519 //*****************************************************************************
520
521 UINT TBasicDialog::CtrlGetText ( const int aResId, char *aReturn, const int aMaxChars) const
522 {
523 return GetDlgItemText( GetHandle(), aResId, aReturn, aMaxChars );
524 }
525 //-----------------------------------------------------------------------------
526
527 BOOL TBasicDialog::CtrlSetText ( const int aResId, LPCSTR aString ) const
528 {
529 HWND ctrl= GetDlgItem( GetHandle(), aResId );
530 SetDlgItemText( GetHandle(), aResId, aString );
531 return ( ctrl != 0 );
532 }
533 //-----------------------------------------------------------------------------
534
535 BOOL TBasicDialog::CtrlSetText ( const int aResId, const int aStrTbleId ) const {
536 char *MsgString= LoadString( aStrTbleId ); // ggf. ""
537 BOOL result= CtrlSetText( aResId, MsgString );
538 _FREELIST(MsgString);
539 return result;
540 }
541 //-----------------------------------------------------------------------------
542
543 BOOL TBasicDialog::CtrlSetFormat ( const int aResId, LPCSTR aFormat, ... ) const
544 {
545 va_list args;
546 va_start( args, aFormat );
547 BOOL result= CtrlSetFormat( aResId, aFormat, args );
548 va_end( args );
549 return result;
550 }
551 BOOL TBasicDialog::CtrlSetFormat ( const int aResId, LPCSTR aFormat, va_list &args ) const
552 {
553 char *buf= GetFormatedStringMaxLen( aFormat, 1024, args );
554 BOOL result= CtrlSetText( aResId, buf );
555 _FREELIST(buf);
556 return result;
557 }
558 //-----------------------------------------------------------------------------
559
560 BOOL TBasicDialog::CtrlSetFormat ( const int aResId, const int aStrTbleIdFormat, ... ) const
561 {
562 va_list args;
563 va_start( args, aStrTbleIdFormat );
564 BOOL result= CtrlSetFormat( aResId, aStrTbleIdFormat, args );
565 va_end( args );
566 return result;
567 }
568 BOOL TBasicDialog::CtrlSetFormat ( const int aResId, const int aStrTbleIdFormat, va_list &args ) const
569 {
570 char *MsgString= LoadString( aStrTbleIdFormat ); // ggf. ""
571 BOOL result= CtrlSetFormat( aResId, MsgString, args );
572 _FREELIST(MsgString);
573 return result;
574 }
575 //*****************************************************************************
576
577 LONG TBasicDialog::CtrlGetLong ( const int aResId, BOOL &aValid ) const
578 {
579 return (LONG)CtrlGetDouble( aResId, 0, '.', aValid );
580 }
581 //-----------------------------------------------------------------------------
582
583 LONG TBasicDialog::CtrlGetLong ( const int aResId, const LONG aMin, const LONG aMax, BOOL &aValid ) const
584 {
585 LONG result= CtrlGetLong( aResId, aValid );
586 return max( aMin, min( aMax, result ) ); // gelesenen Wert ins Intervall [<aMin>..<aMax>] einpassen
587 }
588 //-----------------------------------------------------------------------------
589
590 BOOL TBasicDialog::CtrlSetLong ( const int aResId, const LONG aLong ) const
591 {
592 return CtrlSetDouble( aResId, (double)aLong, 0, '.' );
593 }
594 //*****************************************************************************
595
596 double TBasicDialog::CtrlGetDouble ( const int aResId, const UINT aDigits, const char aDecimal, BOOL &aValid ) const
597 {
598 aValid= FALSE;
599 char buf[ _MAXLENDOUBLE + 1 ]; // + Nullterminierung
600 CtrlGetText(aResId, buf, _MAXLENDOUBLE);
601 if ( !Ctrl(aResId) )
602 return 0.0; // kein solches Steuerelement
603
604 StringReplace( buf, aDecimal, '.' ); // damit sind Komma [,] und Punkt [.] zugelassen :-)
605 if ( !IsDouble(buf, '.') )
606 { // ist kein Double-Wert: FEHLERMELDUNG
607 MessageBox( _NONUMBER, _ERRTITLE, MBSTOP );
608 CtrlSetFocus( aResId );
609 return 0.0;
610 }
611 aValid= TRUE;
612 return String2Double( buf, aDigits, FALSE, '.' ); // bei zu vielen Nachkommastellen abschneiden
613 }
614 //-----------------------------------------------------------------------------
615
616 double TBasicDialog::CtrlGetDouble ( const int aResId, const double aMin, const double aMax, const UINT aDigits, const char aDecimal, BOOL &aValid ) const
617 {
618 double result= CtrlGetDouble( aResId, aDigits, aDecimal, aValid );
619 return max( aMin, min( aMax, result ) ); // gelesenen Wert ins Intervall [<aMin>..<aMax>] einpassen
620 }
621 //-----------------------------------------------------------------------------
622
623 BOOL TBasicDialog::CtrlSetDouble ( const int aResId, const double aDouble, const UINT aDigits, const char aDecimal ) const
624 {
625 char buf[ _MAXLENDOUBLE + 1 ]; // + Nullterminierung
626 Double2String( buf, aDouble, aDigits, TRUE, aDecimal );
627 return CtrlSetText(aResId, buf);
628 }
629 //*****************************************************************************
630
631 float TBasicDialog::CtrlGetFloat ( const int aResId, const UINT aDigits, const char aDecimal, BOOL &aValid ) const
632 {
633 double temp= CtrlGetDouble( aResId, aDigits, aDecimal, aValid );
634 return Double2Float( temp, aDigits );
635 }
636 //-----------------------------------------------------------------------------
637
638 float TBasicDialog::CtrlGetFloat ( const int aResId, const float aMin, const float aMax, const UINT aDigits, const char aDecimal, BOOL &aValid ) const
639 {
640 float result= CtrlGetFloat( aResId, aDigits, aDecimal, aValid );
641 return max( aMin, min( aMax, result ) ); // gelesenen Wert ins Intervall [<aMin>..<aMax>] einpassen
642 }
643 //-----------------------------------------------------------------------------
644
645 BOOL TBasicDialog::CtrlSetFloat ( const int aResId, const float aFloat, const UINT aDigits, const char aDecimal ) const
646 {
647 double temp= Float2Double( aFloat, aDigits );
648 return CtrlSetDouble ( aResId, temp, aDigits, aDecimal );
649 }
650 //*****************************************************************************
651
652 int TBasicDialog::CtrlAddString( const int aResId, LPCSTR aText ) const
653 {
654 HWND ctrl= Ctrl(aResId);
655 if ( !ctrl ) return CB_ERR;
656 return ComboBox_AddString( ctrl, aText );
657 }
658 //-----------------------------------------------------------------------------
659
660 int TBasicDialog::CtrlAddString( const int aResId, const int aStrTbleId ) const
661 {
662 BOOL bValid;
663 int result= -1;
664 char *MsgString= LoadString( aStrTbleId, bValid ); // ggf. ""
665 if ( bValid ) result= CtrlAddString(aResId, MsgString);
666 _FREELIST(MsgString);
667 return result;
668 }
669 //-----------------------------------------------------------------------------
670
671 int TBasicDialog::CtrlDelString( const int aResId, LPCSTR aText ) const
672 {
673 HWND ctrl= Ctrl(aResId);
674 if ( !ctrl ) return CB_ERR;
675 return ComboBox_DeleteString( ctrl, aText );
676 }
677 //-----------------------------------------------------------------------------
678
679 int TBasicDialog::CtrlDelString( const int aResId, const int aStrTbleId ) const
680 {
681 BOOL bValid;
682 int result= -1;
683 char *MsgString= LoadString( aStrTbleId, bValid ); // ggf. ""
684 if ( bValid ) result= CtrlDelString(aResId, MsgString);
685 _FREELIST(MsgString);
686 return result;
687 }
688 //-----------------------------------------------------------------------------
689
690 int TBasicDialog::CtrlGetCount( const int aResId ) const
691 {
692 HWND ctrl= Ctrl(aResId);
693 if ( !ctrl ) return CB_ERR;
694 return ComboBox_GetCount( ctrl );
695 }
696 //-----------------------------------------------------------------------------
697
698 int TBasicDialog::CtrlFindString( const int aResId, LPCSTR aText, const int aStartIdx ) const
699 {
700 HWND ctrl= Ctrl(aResId);
701 if ( !ctrl ) return CB_ERR;
702 return ComboBox_FindString( ctrl, aText, aStartIdx );
703 }
704 //-----------------------------------------------------------------------------
705
706 int TBasicDialog::CtrlFindString( const int aResId, const int aStrTbleId, const int aStartIdx ) const
707 {
708 BOOL bValid;
709 int result= CB_ERR;
710 char *MsgString= LoadString( aStrTbleId, bValid ); // ggf. ""
711 if ( bValid ) result= CtrlFindString( aResId, MsgString, aStartIdx );
712 _FREELIST(MsgString);
713 return result;
714 }
715 //-----------------------------------------------------------------------------
716
717 int TBasicDialog::CtrlGetSel( const int aResId ) const
718 {
719 HWND ctrl= Ctrl(aResId);
720 if ( !ctrl ) return CB_ERR;
721 return ComboBox_GetCurSel( ctrl );
722 }
723 //-----------------------------------------------------------------------------
724
725 char *TBasicDialog::CtrlGetSelString( const int aResId ) const
726 {
727 HWND ctrl= Ctrl(aResId);
728 if ( !ctrl ) {
729 char *result= new char[ 0+1 ]; // nur Nullterminierung
730 strcpy(result, "");
731 return result;
732 }
733 int actLen= 50;
734 while (1) {
735 char *MsgString= new char[actLen+1];
736 int len= ComboBox_GetText( ctrl, MsgString, actLen );
737 if ( len>=actLen && actLen<512 ) { // in jedem Durchlauf 50 Zeichen mehr Platz gewähren
738 _FREELIST(MsgString);
739 actLen+= 50;
740 continue;
741 }
742 if ( len!=CB_ERR ) { // Eintrag existiert
743 char *result= new char[ strlen(MsgString)+1 ]; // + Nullterminierung
744 strcpy(result, MsgString);
745 return result;
746 } else { // Eintrag ist nicht vorhanden
747 char *result= new char[ 0+1 ]; // nur Nullterminierung
748 strcpy(result, "");
749 return result;
750 }
751 }
752 }
753 //-----------------------------------------------------------------------------
754
755 int TBasicDialog::CtrlSetSel( const int aResId, const int aIdx ) const
756 {
757 HWND ctrl= Ctrl(aResId);
758 if ( !ctrl ) return CB_ERR;
759 return ComboBox_SetCurSel( ctrl, aIdx );
760 }
761 //-----------------------------------------------------------------------------
762
763 int TBasicDialog::CtrlSetSelString( const int aResId, LPCSTR aString, const int aStartIdx ) const
764 {
765 HWND ctrl= Ctrl(aResId);
766 if ( !ctrl ) return CB_ERR;
767 return ComboBox_SelectString( ctrl, aStartIdx, aString );
768 }
769 //-----------------------------------------------------------------------------
770
771 int TBasicDialog::CtrlSetSelString( const int aResId, const int aStrTbleId, const int aStartIdx ) const
772 {
773 BOOL bValid;
774 int result= CB_ERR;
775 char *MsgString= LoadString( aStrTbleId, bValid ); // ggf. ""
776 if ( bValid ) result= CtrlSetSelString( aResId, MsgString, aStartIdx );
777 else result= CtrlGetSel(aResId);
778 _FREELIST(MsgString);
779 return result;
780 }
781 //*****************************************************************************
782
783 HWND TBasicDialog::Ctrl ( const int aResId ) const
784 {
785 return GetDlgItem( GetHandle(), aResId );
786 }
787 //-----------------------------------------------------------------------------
788
789 BOOL TBasicDialog::CtrlHasFocus ( const int aResId ) const
790 {
791 return ( GetFocus() == Ctrl(aResId) );
792 }
793 //-----------------------------------------------------------------------------
794
795 BOOL TBasicDialog::CtrlSetFocus ( const int aResId ) const
796 {
797 BOOL result= ( SetFocus( Ctrl(aResId) ) != 0 );
798 SendMessage( Ctrl(aResId), EM_SETSEL, 0, -1);
799 return result;
800 // SendMessage( Ctrl(aCtrl), EM_SETTABSTOPS, 0, 0); //TabStop-Reihenfolge aktualisieren
801 // SendMessage( Ctrl(aCtrl), WM_ACTIVATE, 0, 0); //SelectAll
802 }
803 //-----------------------------------------------------------------------------
804
805 BOOL TBasicDialog::CtrlIsEnabled ( const int aResId ) const
806 {
807 return IsWindowEnabled( Ctrl(aResId) );
808 }
809 //-----------------------------------------------------------------------------
810
811 BOOL TBasicDialog::CtrlSetEnabled ( const int aResId, const BOOL aEnable ) const
812 {
813 return EnableWindow( Ctrl(aResId), aEnable );
814 }
815 //*****************************************************************************
816
817 BOOL TBasicDialog::CtrlIsChecked ( const int aResId ) const
818 {
819 return ( CtrlGetState( aResId ) == BST_CHECKED );
820 }
821 //-----------------------------------------------------------------------------
822
823 BOOL TBasicDialog::CtrlSetChecked ( const int aResId, const BOOL aChecked ) const
824 {
825 if ( aChecked )
826 CtrlSetState( aResId, BST_CHECKED );
827 else
828 CtrlSetState( aResId, BST_UNCHECKED );
829 return CtrlIsChecked( aResId );
830 }
831 //-----------------------------------------------------------------------------
832
833 UINT TBasicDialog::CtrlGetState ( const int aResId ) const
834 {
835 return IsDlgButtonChecked( GetHandle(), aResId );
836 }
837 //-----------------------------------------------------------------------------
838
839 ECheckState TBasicDialog::CtrlGetCheckState ( const int aResId ) const
840 {
841 switch ( CtrlGetState(aResId) ) {
842 case BST_CHECKED:
843 return csChecked;
844
845 case BST_UNCHECKED:
846 return csUnchecked;
847
848 case BST_INDETERMINATE:
849 return csIndeterminate;
850
851 default:
852 return csUnknown;
853 }
854 };
855 //-----------------------------------------------------------------------------
856
857 UINT TBasicDialog::CtrlSetState ( const int aResId, const UINT aCheckState ) const
858 {
859 CheckDlgButton( GetHandle(), aResId, aCheckState );
860 return CtrlGetState( aResId );
861 }
862 //-----------------------------------------------------------------------------
863
864 ECheckState TBasicDialog::CtrlSetCheckState ( const int aResId, const ECheckState aCheckState ) const
865 {
866 switch ( aCheckState ) {
867 case csChecked:
868 CtrlSetState(aResId, BST_CHECKED);
869 break;
870
871 case csUnchecked:
872 CtrlSetState(aResId, BST_UNCHECKED);
873 break;
874
875 case csIndeterminate:
876 CtrlSetState(aResId, BST_INDETERMINATE);
877 break;
878 }
879 return CtrlGetCheckState(aResId);
880 }
881
882 //#############################################################################
883 // TModalDlg
884 //#############################################################################
885
886 TModalDlg::TModalDlg(const char *aResName, HINSTANCE aInstance)
887 : TBasicDialog(aResName, aInstance),
888 m_Handler(0)
889 {
890 m_Handler= (FARPROC)TBasicWindow::EventHandler;
891 }
892 //-----------------------------------------------------------------------------
893
894 TModalDlg::~TModalDlg ( void )
895 {
896 UnregisterWindow(); // spätestens jetzt haben unser Handle verloren
897 if ( m_Handler )
898 {
899 m_Handler= 0;
900 }
901 };
902 //-----------------------------------------------------------------------------
903
904 int TModalDlg::ExecuteDialog ( HWND aParentWindow )
905 {
906 TBasicWindow::s_WaitingWindow= this; // wartet auf sein Fensterhandle; wird nach der ersten Botschaft automatisch wieder 0 gesetzt
907 int result= DialogBoxParam( GetInstance(), GetResName(), aParentWindow, (DLGPROC)m_Handler, 0l ); // pausiert, bis das Dialogfenster geschlossen wird; Rückgabewert ist der Schließungsgrund
908 UnregisterWindow(); // wir haben unser Handle soeben verloren
909 return result;
910 };
911 //-----------------------------------------------------------------------------
912
913 void TModalDlg::Dlg_OnCommand ( HWND, int aId, HWND, UINT )
914 {
915 if ( (aId == IDCLOSE) || (aId == IDCANCEL) || (aId == IDABORT) || ( (aId == IDOK) && (CanClose()) ) )
916 { // Dialogfenster schließen
917 LeaveDialog();
918 EndDialog( GetHandle(), aId ); // schließt das Dialogfenster und gibt <id> als Schließungsgrund an DialogBoxParam zurück
919 }
920 };
921
922 //#############################################################################
923 // TModelessDlg
924 //#############################################################################
925
926 //-----------------------------------------------------------------------------
927 TModelessDlg::TModelessDlg(const char *aResName, TModelessDlg **aReference, HINSTANCE aInstance)
928 : TBasicDialog(aResName, aInstance),
929 m_Handler(0),
930 m_Reference(0)
931 {
932 m_Handler= (DLGPROC)(FARPROC)TBasicWindow::EventHandler;
933 m_Reference= aReference;
934 }
935 //-----------------------------------------------------------------------------
936
937 TModelessDlg::~TModelessDlg ( void )
938 {
939 if ( m_Window )
940 {
941 DestroyWindow( m_Window );
942 UnregisterWindow(); // spätestens jetzt haben unser Handle verloren
943 m_Window= 0;
944 }
945 if ( m_Handler )
946 {
947 m_Handler= 0;
948 }
949 *m_Reference= 0;
950 };
951 //-----------------------------------------------------------------------------
952
953 BOOL TModelessDlg::Initialize ( HINSTANCE aInstance, HWND aParentWnd )
954 {
955 TBasicWindow::s_WaitingWindow= this; // wartet auf sein Fensterhandle; wird nach der ersten Botschaft automatisch wieder 0 gesetzt
956 m_Window= CreateDialog( aInstance, GetResName(), aParentWnd, (DLGPROC)TBasicWindow::EventHandler );
957 if ( m_Window == 0 )
958 {
959 MessageBox( _NOWINDOW, _ERRTITLE, MBSTOP);
960 return FALSE;
961 }
962 ShowWindow( m_Window, SW_SHOW );
963 return TRUE;
964 };
965 //-----------------------------------------------------------------------------
966
967 void TModelessDlg::Dlg_OnCommand ( HWND, int aId, HWND, UINT )
968 {
969 if ( (aId == IDCANCEL) || (aId == IDABORT) || ( (aId == IDOK) && (CanClose()) ) )
970 { // Dialogfenster schließen
971 LeaveDialog();
972 delete this; // schließt das Fenster und hebt seine Registrierung auf; es werden keine Botschaften mehr verschickt
973 }
974 };
975
976 //#############################################################################
977 // TBasicMDIWindow
978 //#############################################################################
979
980 TBasicMDIWindow::TBasicMDIWindow ( HINSTANCE aInstance ) : TBasicWindow(aInstance)
981 {
982 strcpy(m_Title, "");
983 m_Showing= false;
984 }
985 //-----------------------------------------------------------------------------
986
987 TBasicMDIWindow::~TBasicMDIWindow ( void )
988 {
989 if ( GetHandle() )
990 SetWindowLong(GetHandle(), 1, 0); // UnregisterWindow bei ~TBasicWindow (mit UnregisterWindow ist GetHandle()==0)
991 }
992
993 //*****************************************************************************
994 // Anzeigen & Co
995 //*****************************************************************************
996
997 LRESULT TBasicMDIWindow::Show ( HWND aParent, const int aX, const int aY, const int aWidth, const int aHeight)
998 {
999 if ( m_Showing ) return BringWindowToTop(GetHandle()); // Fensterklasse und Fenster nicht erneut regiestrieren!!!
1000
1001 m_Showing= true;
1002 //Fensterklasse registrieren
1003 WNDCLASS wndClass, wndAsk;
1004 wndClass.style= CS_HREDRAW | CS_VREDRAW;
1005 wndClass.cbClsExtra= 0;
1006 wndClass.cbWndExtra= sizeof(HINSTANCE)+sizeof(LPARAM); // zu reservierender Speicher für mdiCreate.hOwner und mdiCreate.lParam
1007 wndClass.hInstance= GetInstance();
1008 wndClass.hIcon= GetIcon();
1009 wndClass.hCursor= GetCursor();
1010 wndClass.hbrBackground= GetBkColor();
1011 wndClass.lpszMenuName= "";
1012 wndClass.lpszClassName= (LPSTR)ClassName();
1013 wndClass.lpfnWndProc= TBasicMDIWindow::EventHandler;
1014 if ( !GetClassInfo(wndClass.hInstance, wndClass.lpszClassName, &wndAsk) )
1015 RegisterClass(&wndClass);
1016
1017 // Fenster anzeigen
1018 MDICREATESTRUCT mdiCreate;
1019 mdiCreate.szClass= (LPSTR)ClassName();
1020 mdiCreate.szTitle= (LPSTR)m_Title;
1021 mdiCreate.hOwner= GetInstance();
1022 mdiCreate.x= ( (aX != -1) ? aX : CW_USEDEFAULT );
1023 mdiCreate.y= ( (aY != -1) ? aY : CW_USEDEFAULT );
1024 mdiCreate.cx= ( (aWidth != -1) ? aWidth : CW_USEDEFAULT );
1025 mdiCreate.cy= ( (aHeight != -1) ? aHeight : CW_USEDEFAULT );
1026 mdiCreate.style= 0;
1027 mdiCreate.lParam= (LPARAM)this;
1028 s_WaitingWindow= this; // die eigentliche Registrierung erfolgt über mdiCreate.lParam und WM_CREATE, davor werden jedoch auch WM_GETMINMAXINFO, WM_NCCREATE und WM_NCCALCSIZE versendet, die nicht ohne s_WaitingWindow zugeordnet werden könnten
1029 return SendMessage(aParent, WM_MDICREATE, NULL, (LPARAM)&mdiCreate);
1030 }
1031 //-----------------------------------------------------------------------------
1032
1033 BOOL TBasicMDIWindow::SetTitle ( void )
1034 {
1035 if ( GetHandle() )
1036 SetWindowText(GetHandle(), (LPSTR)m_Title);
1037 return TRUE;
1038 }
1039
1040 //*****************************************************************************
1041 // EREIGNISSE
1042 //*****************************************************************************
1043
1044 void TBasicMDIWindow::OnPaint ( void )
1045 {
1046 PAINTSTRUCT ps;
1047 HDC hdc= BeginPaint(GetHandle(), &ps);
1048 DoPaint(hdc, &ps);
1049 EndPaint(GetHandle(), &ps);
1050 }
1051 //-----------------------------------------------------------------------------
1052
1053 void TBasicMDIWindow::OnHotKey ( LPARAM lParam )
1054 {
1055 for (UINT i= 0; i < m_HotKeys.size(); i++ )
1056 {
1057 THotKey *hk= m_HotKeys[i];
1058 if ( (hk) && (hk->IsEqual(lParam)) )
1059 {
1060 OnCommand( hk->m_Cmd, 0 );
1061 return;
1062 }
1063 }
1064 }
1065 //-----------------------------------------------------------------------------
1066
1067 LRESULT TBasicMDIWindow::OnEvent ( HWND, UINT message, WPARAM wParam, LPARAM lParam )
1068 {
1069 switch (message)
1070 {
1071 case WM_SYSCOLORCHANGE:
1072 //! Ctl3dColorChange();
1073 return 0l;
1074
1075 case WM_KEYDOWN:
1076 OnKeyDown(wParam, lParam);
1077 break;
1078
1079 case WM_LBUTTONDOWN:
1080 OnLButtonDown(wParam, lParam);
1081 break;
1082
1083 case WM_LBUTTONUP:
1084 OnLButtonUp(wParam, lParam);
1085 break;
1086
1087 case WM_RBUTTONDOWN:
1088 OnRButtonDown(wParam, lParam);
1089 break;
1090
1091 case WM_MOUSEMOVE:
1092 OnMouseMove(wParam, lParam);
1093 break;
1094
1095 case WM_COMMAND:
1096 OnCommand(wParam, lParam);
1097 break;
1098
1099 case WM_INITMENUPOPUP:
1100 OnPopupMenuInit(wParam, lParam);
1101 break;
1102
1103 case WM_MENUSELECT:
1104 OnMenuSelect(wParam, lParam);
1105 break;
1106
1107 case WM_PAINT:
1108 OnPaint();
1109 break;
1110
1111 case WM_SETFOCUS:
1112 OnFocus();
1113 break;
1114
1115 case WM_SIZE:
1116 OnSize(wParam, lParam);
1117 break;
1118
1119 case WM_TIMER:
1120 OnTimer(wParam, lParam);
1121 break;
1122
1123 case WM_RENDERFORMAT:
1124 OnRenderFormat(wParam, lParam);
1125 break;
1126
1127 case WM_RENDERALLFORMATS:
1128 OnRenderAllFormats(wParam, lParam);
1129 break;
1130
1131 case WM_MDIDESTROY:
1132 CanClose(); // der Rückgabewert wird nicht ausgewertet?!
1133 break;
1134
1135 case WM_DESTROY:
1136 // wenn noch nicht alle Daten gespeichert sind: ABBRUCH (sonst folgt WM_NCDESTROY)
1137 if ( !CanClose() )
1138 return 0l;
1139 break;
1140 } // end switch
1141 return FALSE; // d.h. DefMDIChildProc trotzdem aufrufen
1142 }
1143
1144 //*****************************************************************************
1145 //STATIC
1146 //*****************************************************************************
1147
1148 LRESULT CALLBACK TBasicMDIWindow::EventHandler ( HWND hWindow, UINT message, WPARAM wParam, LPARAM lParam )
1149 {
1150 BOOL aValid= TRUE;
1151 switch ( message )
1152 {
1153 case WM_CREATE:
1154 if ( lParam )
1155 { // unser lParam ist ein Zeiger auf eine CREATESTRUCT ...
1156 CREATESTRUCT *a= (CREATESTRUCT *)lParam;
1157 if ( a )
1158 { // ... im Member lpCreateParams liegt dort ein Zeiger eine MDICREATESTRUCT
1159 MDICREATESTRUCT *b= (MDICREATESTRUCT *)a->lpCreateParams;
1160 if ( b )
1161 { // ... darin liegt im lParam unser Fensterobjekt :-)
1162 TBasicMDIWindow *self= (TBasicMDIWindow *)b->lParam;
1163 if ( (self) && (self->CanOpen()) )
1164 {
1165 SetWindowLong(hWindow, 1, (DWORD)self);
1166 self->RegisterWindow(hWindow);
1167 self->OnCreate();
1168 break;
1169 }
1170 else if ( self )
1171 self->OnNotCreated(); // CanOpen==FALSE
1172 }
1173 }
1174 }
1175 return -1;
1176
1177 // Tastaturereignisse gehen NUR an das aktive Fenster
1178 case WM_HOTKEY:
1179 case WM_KEYDOWN:
1180 case WM_KEYUP:
1181 {
1182 // Objekt aus der Liste der registrierten Fenster ermitteln; damit endlich auch Zugriff auf Member
1183 TBasicMDIWindow *self= (TBasicMDIWindow *)Handle2Object(GetFocus()); // nur wenn Fenster aktiv, sonst fangen wir die Tastenkombinationen auch wenn unsere Anwendung inaktiv ist!!!
1184 if ( self ) switch ( message ) {
1185 case WM_HOTKEY:
1186 self->OnHotKey(lParam);
1187 break;
1188
1189 case WM_KEYDOWN:
1190 self->OnKeyDown(wParam, lParam);
1191 break;
1192
1193 case WM_KEYUP:
1194 self->OnKeyUp(wParam, lParam);
1195 break;
1196 }
1197 break;
1198 }
1199
1200 case WM_NCDESTROY:
1201 {
1202 TBasicMDIWindow *self= (TBasicMDIWindow *)GetWindowLong(hWindow, 1);
1203 _FREEOBJ(self);
1204 break;
1205 }
1206
1207 default:
1208 BOOL aValid= FALSE;
1209 LRESULT result;
1210 if ( (message != WM_CREATE) && (message != WM_NCDESTROY) )
1211 result= TBasicWindow::EventHandlerEx( hWindow, message, wParam, lParam, aValid );
1212 if ( (aValid) && (result != FALSE) )
1213 return result; // Botschaft wurde an OnEvent des entsprechenden Fensters weitergeleitet
1214 }
1215 return DefMDIChildProc(hWindow, message, wParam, lParam);
1216 }
1217
1218 //#############################################################################
1219 // LastLine
1220 //#############################################################################
1221