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";
27 #else 28 const char _MSGTITLE[]= "Message"; 29 const char _NONUMBER[]= "This value is not a number!\nPlease check your input."; 30 const char _NOWINDOW[]= "Window can't be created!"; 31 const char _ERRTITLE[]= "ERROR";
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