1 /* 2 * Copyright 2003, 2004, 2005 Martin Fuchs 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 20 // 21 // Explorer clone 22 // 23 // window.cpp 24 // 25 // Martin Fuchs, 23.07.2003 26 // 27 28 29 #include <precomp.h> 30 31 WindowClass::WindowClass(LPCTSTR classname, UINT style_, WNDPROC wndproc) 32 { 33 memset(this, 0, sizeof(WNDCLASSEX)); 34 35 cbSize = sizeof(WNDCLASSEX); 36 style = style_; 37 hInstance = g_Globals._hInstance; 38 hCursor = LoadCursor(0, IDC_ARROW); 39 this->hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); 40 lpszClassName = classname; 41 lpfnWndProc = wndproc; 42 43 _atomClass = 0; 44 } 45 46 47 IconWindowClass::IconWindowClass(LPCTSTR classname, UINT nid, UINT style, WNDPROC wndproc) 48 : WindowClass(classname, style, wndproc) 49 { 50 hIcon = ResIcon(nid); 51 hIconSm = SmallIcon(nid); 52 } 53 54 55 Window::WindowMap Window::s_wnd_map; 56 57 Window::CREATORFUNC Window::s_window_creator = NULL; 58 const void* Window::s_new_info = NULL; 59 60 HHOOK Window::s_hcbtHook = 0; 61 62 63 Window::StaticWindowData& Window::GetStaticWindowData() 64 { 65 static StaticWindowData s_initialized_data; 66 67 return s_initialized_data; 68 } 69 70 71 Window::Window(HWND hwnd) 72 : WindowHandle(hwnd) 73 { 74 Lock lock(GetStaticWindowData()._map_crit_sect); // protect access to s_wnd_map 75 76 s_wnd_map[_hwnd] = this; 77 } 78 79 Window::~Window() 80 { 81 Lock lock(GetStaticWindowData()._map_crit_sect); // protect access to s_wnd_map 82 83 s_wnd_map.erase(_hwnd); 84 } 85 86 87 HWND Window::Create(CREATORFUNC creator, DWORD dwExStyle, 88 LPCTSTR lpClassName, LPCTSTR lpWindowName, 89 DWORD dwStyle, int x, int y, int w, int h, 90 HWND hwndParent, HMENU hMenu/*, LPVOID lpParam*/) 91 { 92 Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info 93 94 s_window_creator = creator; 95 s_new_info = NULL; 96 97 return CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, 98 x, y, w, h, 99 hwndParent, hMenu, g_Globals._hInstance, 0/*lpParam*/); 100 } 101 102 HWND Window::Create(CREATORFUNC_INFO creator, const void* info, DWORD dwExStyle, 103 LPCTSTR lpClassName, LPCTSTR lpWindowName, 104 DWORD dwStyle, int x, int y, int w, int h, 105 HWND hwndParent, HMENU hMenu/*, LPVOID lpParam*/) 106 { 107 Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info 108 109 s_window_creator = (CREATORFUNC) creator; 110 s_new_info = info; 111 112 return CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, 113 x, y, w, h, 114 hwndParent, hMenu, g_Globals._hInstance, 0/*lpParam*/); 115 } 116 117 118 Window* Window::create_mdi_child(const ChildWndInfo& info, const MDICREATESTRUCT& mcs, CREATORFUNC_INFO creator) 119 { 120 Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info 121 122 s_window_creator = (CREATORFUNC) creator; 123 s_new_info = &info; 124 125 s_hcbtHook = SetWindowsHookEx(WH_CBT, MDICBTHookProc, 0, GetCurrentThreadId()); 126 127 HWND hwnd = (HWND) SendMessage(info._hmdiclient, WM_MDICREATE, 0, (LPARAM)&mcs); 128 129 // end hook in case it's not already done 130 if (s_hcbtHook) 131 UnhookWindowsHookEx(s_hcbtHook); 132 133 Window* child = get_window(hwnd); 134 s_new_info = NULL; 135 136 if (child && (!hwnd || !child->_hwnd)) 137 child = NULL; 138 139 return child; 140 } 141 142 LRESULT CALLBACK Window::MDICBTHookProc(int code, WPARAM wparam, LPARAM lparam) 143 { 144 if (code == HCBT_CREATEWND) { 145 UnhookWindowsHookEx(s_hcbtHook); // use the hook only for the first created window 146 s_hcbtHook = 0; 147 148 HWND hwnd = (HWND)wparam; 149 150 // create Window controller and associate it with the window handle 151 Window* child = get_window(hwnd); 152 153 if (!child) 154 child = create_controller(hwnd); 155 } 156 157 return CallNextHookEx(s_hcbtHook, code, wparam, lparam); 158 } 159 160 161 /* 162 Window* Window::create_property_sheet(PropertySheetDialog* ppsd, CREATORFUNC creator, const void* info) 163 { 164 Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info 165 166 s_window_creator = creator; 167 s_new_info = info; 168 169 s_hcbtHook = SetWindowsHookEx(WH_CBT, PropSheetCBTHookProc, 0, GetCurrentThreadId()); 170 171 HWND hwnd = (HWND) PropertySheet(ppsd); 172 173 UnhookWindowsHookEx(s_hcbtHook); 174 175 Window* child = get_window(hwnd); 176 s_new_info = NULL; 177 178 if (child && (!hwnd || !child->_hwnd)) 179 child = NULL; 180 181 return child; 182 } 183 */ 184 185 LRESULT CALLBACK Window::PropSheetCBTHookProc(int code, WPARAM wparam, LPARAM lparam) 186 { 187 if (code == HCBT_CREATEWND) { 188 HWND hwnd = (HWND)wparam; 189 190 // create Window controller and associate it with the window handle 191 Window* child = get_window(hwnd); 192 193 if (!child) 194 child = create_controller(hwnd); 195 } 196 197 return CallNextHookEx(s_hcbtHook, code, wparam, lparam); 198 } 199 200 201 /// get window controller from window handle 202 203 Window* Window::get_window(HWND hwnd) 204 { 205 { 206 Lock lock(GetStaticWindowData()._map_crit_sect); // protect access to s_wnd_map 207 208 WindowMap::const_iterator found = s_wnd_map.find(hwnd); 209 210 if (found!=s_wnd_map.end()) 211 return found->second; 212 } 213 214 return NULL; 215 } 216 217 218 /// create controller for a new window 219 220 Window* Window::create_controller(HWND hwnd) 221 { 222 if (s_window_creator) { // protect for recursion and create the window object only for the first window 223 Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info 224 225 const void* info = s_new_info; 226 s_new_info = NULL; 227 228 CREATORFUNC window_creator = s_window_creator; 229 s_window_creator = NULL; 230 231 if (info) 232 return CREATORFUNC_INFO(window_creator)(hwnd, info); 233 else 234 return CREATORFUNC(window_creator)(hwnd); 235 } 236 237 return NULL; 238 } 239 240 241 LRESULT Window::Init(LPCREATESTRUCT pcs) 242 { 243 return 0; 244 } 245 246 247 LRESULT CALLBACK Window::WindowWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) 248 { 249 Window* pThis = get_window(hwnd); 250 251 if (!pThis) 252 pThis = create_controller(hwnd); 253 254 if (pThis) { 255 switch(nmsg) { 256 case WM_COMMAND: 257 return pThis->Command(LOWORD(wparam), HIWORD(wparam)); 258 259 case WM_NOTIFY: 260 return pThis->Notify(wparam, (NMHDR*)lparam); 261 262 case WM_NOTIFYFORMAT: 263 return NFR_CURRENT; 264 265 case WM_CREATE: 266 return pThis->Init((LPCREATESTRUCT)lparam); 267 268 case WM_NCDESTROY: 269 delete pThis; 270 return 0; 271 272 default: 273 return pThis->WndProc(nmsg, wparam, lparam); 274 } 275 } 276 else 277 return DefWindowProc(hwnd, nmsg, wparam, lparam); 278 } 279 280 LRESULT Window::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 281 { 282 return DefWindowProc(_hwnd, nmsg, wparam, lparam); 283 } 284 285 int Window::Command(int id, int code) 286 { 287 return 1; // no command handler found 288 } 289 290 int Window::Notify(int id, NMHDR* pnmh) 291 { 292 return 0; 293 } 294 295 void Window::CancelModes() 296 { 297 PostMessage(HWND_BROADCAST, WM_CANCELMODE, 0, 0); 298 } 299 300 301 SubclassedWindow::SubclassedWindow(HWND hwnd) 302 : super(hwnd) 303 { 304 _orgWndProc = SubclassWindow(_hwnd, SubclassedWndProc); 305 306 if (!_orgWndProc) 307 delete this; 308 } 309 310 LRESULT CALLBACK SubclassedWindow::SubclassedWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) 311 { 312 SubclassedWindow* pThis = GET_WINDOW(SubclassedWindow, hwnd); 313 assert(pThis); 314 315 if (pThis) { 316 switch(nmsg) { 317 case WM_COMMAND: 318 if (!pThis->Command(LOWORD(wparam), HIWORD(wparam))) 319 return 0; 320 break; 321 322 case WM_NOTIFY: 323 return pThis->Notify(wparam, (NMHDR*)lparam); 324 325 case WM_NOTIFYFORMAT: 326 return NFR_CURRENT; 327 328 case WM_CREATE: 329 return pThis->Init((LPCREATESTRUCT)lparam); 330 331 case WM_NCDESTROY: 332 delete pThis; 333 return 0; 334 335 default: 336 return pThis->WndProc(nmsg, wparam, lparam); 337 } 338 } 339 340 return CallWindowProc(pThis->_orgWndProc, hwnd, nmsg, wparam, lparam); 341 } 342 343 LRESULT SubclassedWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 344 { 345 return CallWindowProc(_orgWndProc, _hwnd, nmsg, wparam, lparam); 346 } 347 348 int SubclassedWindow::Command(int id, int code) 349 { 350 return 1; // no command handler found 351 } 352 353 int SubclassedWindow::Notify(int id, NMHDR* pnmh) 354 { 355 return CallWindowProc(_orgWndProc, _hwnd, WM_NOTIFY, id, (LPARAM)pnmh); 356 } 357 358 359 ChildWindow::ChildWindow(HWND hwnd, const ChildWndInfo& info) 360 : super(hwnd), 361 _hwndFrame(GetParent(info._hmdiclient)) 362 { 363 _focus_pane = 0; 364 _split_pos = DEFAULT_SPLIT_POS; 365 _last_split = DEFAULT_SPLIT_POS; 366 } 367 368 369 ChildWindow* ChildWindow::create(const ChildWndInfo& info, const RECT& rect, CREATORFUNC_INFO creator, 370 LPCTSTR classname, LPCTSTR title, DWORD style) 371 { 372 MDICREATESTRUCT mcs; 373 374 mcs.szClass = classname; 375 mcs.szTitle = title; 376 mcs.hOwner = g_Globals._hInstance; 377 mcs.x = rect.left, 378 mcs.y = rect.top; 379 mcs.cx = rect.right - rect.left; 380 mcs.cy = rect.bottom - rect.top; 381 mcs.style = style; 382 mcs.lParam = 0; 383 384 return static_cast<ChildWindow*>(create_mdi_child(info, mcs, creator)); 385 } 386 387 388 LRESULT ChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 389 { 390 switch(nmsg) { 391 case WM_PAINT: { 392 RECT rc; 393 PaintCanvas canvas(_hwnd); 394 ClientRect rt(_hwnd); 395 rt.left = _split_pos-SPLIT_WIDTH/2; 396 rt.right = _split_pos+SPLIT_WIDTH/2+1; 397 HBRUSH lastBrush = SelectBrush(canvas, GetStockBrush(COLOR_SPLITBAR)); 398 Rectangle(canvas, rt.left, rt.top-1, rt.right, rt.bottom+1); 399 SetRect(&rc, rt.left, rt.top-1, rt.right, rt.bottom+1); 400 DrawEdge(canvas, &rc, EDGE_RAISED, BF_RECT); 401 SelectObject(canvas, lastBrush); 402 break;} 403 404 case WM_SETCURSOR: 405 if (LOWORD(lparam) == HTCLIENT) { 406 POINT pt; 407 GetCursorPos(&pt); 408 ScreenToClient(_hwnd, &pt); 409 410 if (pt.x>=_split_pos-SPLIT_WIDTH/2 && pt.x<_split_pos+SPLIT_WIDTH/2+1) { 411 SetCursor(LoadCursor(0, IDC_SIZEWE)); 412 return TRUE; 413 } 414 } 415 goto def; 416 417 case WM_SIZE: 418 if (wparam != SIZE_MINIMIZED) 419 resize_children(LOWORD(lparam), HIWORD(lparam)); 420 goto def; 421 422 case WM_GETMINMAXINFO: 423 DefMDIChildProc(_hwnd, nmsg, wparam, lparam); 424 425 {LPMINMAXINFO lpmmi = (LPMINMAXINFO)lparam; 426 427 lpmmi->ptMaxTrackSize.x <<= 1; // 2*GetSystemMetrics(SM_CXSCREEN) / SM_CXVIRTUALSCREEN 428 lpmmi->ptMaxTrackSize.y <<= 1; // 2*GetSystemMetrics(SM_CYSCREEN) / SM_CYVIRTUALSCREEN 429 break;} 430 431 case WM_LBUTTONDOWN: { 432 int x = GET_X_LPARAM(lparam); 433 434 ClientRect rt(_hwnd); 435 436 if (x>=_split_pos-SPLIT_WIDTH/2 && x<_split_pos+SPLIT_WIDTH/2+1) { 437 _last_split = _split_pos; 438 SetCapture(_hwnd); 439 } 440 441 break;} 442 443 case WM_LBUTTONUP: 444 if (GetCapture() == _hwnd) 445 ReleaseCapture(); 446 break; 447 448 case WM_KEYDOWN: 449 if (wparam == VK_ESCAPE) 450 if (GetCapture() == _hwnd) { 451 _split_pos = _last_split; 452 ClientRect rt(_hwnd); 453 resize_children(rt.right, rt.bottom); 454 _last_split = -1; 455 ReleaseCapture(); 456 SetCursor(LoadCursor(0, IDC_ARROW)); 457 } 458 break; 459 460 case WM_MOUSEMOVE: 461 if (GetCapture() == _hwnd) { 462 int x = GET_X_LPARAM(lparam); 463 464 ClientRect rt(_hwnd); 465 466 if (x>=0 && x<rt.right) { 467 _split_pos = x; 468 resize_children(rt.right, rt.bottom); 469 rt.left = x-SPLIT_WIDTH/2; 470 rt.right = x+SPLIT_WIDTH/2+1; 471 InvalidateRect(_hwnd, &rt, FALSE); 472 UpdateWindow(_left_hwnd); 473 UpdateWindow(_hwnd); 474 UpdateWindow(_right_hwnd); 475 } 476 } 477 break; 478 479 case PM_DISPATCH_COMMAND: 480 switch(LOWORD(wparam)) { 481 case ID_GO_BACK: 482 if (!_url_history.empty()) { 483 const String& url = jump_to_int(_url_history.top()); 484 485 if (jump_to_int(url)) 486 set_url(url); 487 488 _url_history.pop(); 489 } 490 break; 491 492 case ID_GO_FORWARD: 493 //@@ 494 break; 495 496 case ID_GO_UP: 497 ///@todo 498 break; 499 500 case ID_GO_HOME: 501 //@@ 502 break; 503 504 default: 505 return FALSE; 506 } 507 return TRUE; 508 509 case WM_MDIACTIVATE: 510 if ((HWND)lparam == _hwnd) { 511 SendMessage(_hwndFrame, PM_SETSTATUSTEXT, 0, (LPARAM)_statusText.c_str()); 512 SendMessage(_hwndFrame, PM_URL_CHANGED, 0, (LPARAM)_url.c_str()); 513 } 514 break; 515 516 case PM_JUMP_TO_URL: 517 return go_to((LPCTSTR)lparam)? TRUE: FALSE; 518 519 default: def: 520 return DefMDIChildProc(_hwnd, nmsg, wparam, lparam); 521 } 522 523 return 0; 524 } 525 526 527 void ChildWindow::resize_children(int cx, int cy) 528 { 529 HDWP hdwp = BeginDeferWindowPos(2); 530 RECT rt; 531 532 rt.left = 0; 533 rt.top = 0; 534 rt.right = cx; 535 rt.bottom = cy; 536 537 if (_left_hwnd) { 538 cx = _split_pos + SPLIT_WIDTH/2; 539 540 hdwp = DeferWindowPos(hdwp, _left_hwnd, 0, rt.left, rt.top, _split_pos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE); 541 } else { 542 _split_pos = 0; 543 cx = 0; 544 } 545 546 if (_right_hwnd) 547 hdwp = DeferWindowPos(hdwp, _right_hwnd, 0, rt.left+cx+1, rt.top, rt.right-cx, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE); 548 549 EndDeferWindowPos(hdwp); 550 } 551 552 553 bool ChildWindow::go_to(LPCTSTR url) 554 { 555 const String& url_str = jump_to_int(url); 556 557 if (!url_str.empty()) { 558 set_url(url_str); 559 560 _url_history.push(url_str); 561 562 return true; 563 } else 564 return false; 565 } 566 567 void ChildWindow::set_url(LPCTSTR url) 568 { 569 if (_url != url) { 570 _url = url; 571 572 SendMessage(_hwndFrame, PM_URL_CHANGED, 0, (LPARAM)url); 573 } 574 } 575 576 577 WindowSet Window::s_pretranslate_windows; 578 579 void Window::register_pretranslate(HWND hwnd) 580 { 581 s_pretranslate_windows.insert(hwnd); 582 } 583 584 void Window::unregister_pretranslate(HWND hwnd) 585 { 586 s_pretranslate_windows.erase(hwnd); 587 } 588 589 BOOL Window::pretranslate_msg(LPMSG pmsg) 590 { 591 if ((pmsg->message != WM_KEYDOWN) && 592 (pmsg->message != WM_SYSKEYDOWN) && 593 (pmsg->message != WM_SYSCHAR) && 594 (pmsg->message != WM_CHAR)) 595 { 596 return FALSE; 597 } 598 599 for(WindowSet::const_iterator it=Window::s_pretranslate_windows.begin(); it!=s_pretranslate_windows.end(); ++it) 600 if (SendMessage(*it, PM_TRANSLATE_MSG, 0, (LPARAM)pmsg)) 601 return TRUE; 602 603 return FALSE; 604 } 605 606 607 WindowSet Window::s_dialogs; 608 609 void Window::register_dialog(HWND hwnd) 610 { 611 s_dialogs.insert(hwnd); 612 } 613 614 void Window::unregister_dialog(HWND hwnd) 615 { 616 s_dialogs.erase(hwnd); 617 } 618 619 BOOL Window::dispatch_dialog_msg(MSG* pmsg) 620 { 621 for(WindowSet::const_iterator it=Window::s_dialogs.begin(); it!=s_dialogs.end(); ++it) 622 if (IsDialogMessage(*it, pmsg)) 623 return TRUE; 624 625 return FALSE; 626 } 627 628 629 int Window::MessageLoop() 630 { 631 MSG msg; 632 633 while(GetMessage(&msg, 0, 0, 0)) { 634 try { 635 if (pretranslate_msg(&msg)) 636 continue; 637 638 if (dispatch_dialog_msg(&msg)) 639 continue; 640 641 TranslateMessage(&msg); 642 643 try { 644 DispatchMessage(&msg); 645 } catch(COMException& e) { 646 HandleException(e, 0); 647 } 648 } catch(COMException& e) { 649 HandleException(e, 0); 650 } 651 } 652 653 return msg.wParam; 654 } 655 656 657 LRESULT Window::SendParent(UINT nmsg, WPARAM wparam, LPARAM lparam) 658 { 659 HWND parent = GetParent(_hwnd); 660 661 if (!parent) 662 return 0; 663 664 return SendMessage(parent, nmsg, wparam, lparam); 665 } 666 667 LRESULT Window::PostParent(UINT nmsg, WPARAM wparam, LPARAM lparam) 668 { 669 HWND parent = GetParent(_hwnd); 670 671 if (!parent) 672 return 0; 673 674 return PostMessage(parent, nmsg, wparam, lparam); 675 } 676 677 678 PreTranslateWindow::PreTranslateWindow(HWND hwnd) 679 : super(hwnd) 680 { 681 register_pretranslate(hwnd); 682 } 683 684 PreTranslateWindow::~PreTranslateWindow() 685 { 686 unregister_pretranslate(_hwnd); 687 } 688 689 690 Dialog::Dialog(HWND hwnd) 691 : super(hwnd) 692 { 693 register_dialog(hwnd); 694 } 695 696 Dialog::~Dialog() 697 { 698 unregister_dialog(_hwnd); 699 } 700 701 int Dialog::DoModal(UINT nid, CREATORFUNC creator, HWND hwndParent) 702 { 703 Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info 704 705 s_window_creator = creator; 706 s_new_info = NULL; 707 708 ///@todo call Window::pretranslate_msg() 709 710 return DialogBoxParam(g_Globals._hInstance, MAKEINTRESOURCE(nid), hwndParent, DialogProc, 0/*lpParam*/); 711 } 712 713 int Dialog::DoModal(UINT nid, CREATORFUNC_INFO creator, const void* info, HWND hwndParent) 714 { 715 Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info 716 717 s_window_creator = (CREATORFUNC) creator; 718 s_new_info = NULL; 719 720 ///@todo call Window::pretranslate_msg() 721 722 return DialogBoxParam(g_Globals._hInstance, MAKEINTRESOURCE(nid), hwndParent, DialogProc, 0/*lpParam*/); 723 } 724 725 INT_PTR CALLBACK Window::DialogProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) 726 { 727 Window* pThis = get_window(hwnd); 728 729 if (pThis) { 730 switch(nmsg) { 731 case WM_COMMAND: 732 pThis->Command(LOWORD(wparam), HIWORD(wparam)); 733 return TRUE; // message has been processed 734 735 case WM_NOTIFY: 736 pThis->Notify(wparam, (NMHDR*)lparam); 737 return TRUE; // message has been processed 738 739 case WM_NOTIFYFORMAT: 740 SetWindowLongPtr(hwnd, DWLP_MSGRESULT, NFR_CURRENT); // set return value NFR_CURRENT 741 return TRUE; // message has been processed 742 743 case WM_NCDESTROY: 744 delete pThis; 745 return TRUE; // message has been processed 746 747 default: 748 return pThis->WndProc(nmsg, wparam, lparam); 749 } 750 } else if (nmsg == WM_INITDIALOG) { 751 pThis = create_controller(hwnd); 752 753 if (pThis) 754 return pThis->Init(NULL); 755 } 756 757 return FALSE; // message has not been processed 758 } 759 760 LRESULT Dialog::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 761 { 762 return FALSE; // message has not been processed 763 } 764 765 int Dialog::Command(int id, int code) 766 { 767 if (code == BN_CLICKED) { 768 EndDialog(_hwnd, id); 769 return 0; // message has been processed 770 } 771 772 return 1; 773 } 774 775 776 ResizeManager::ResizeManager(HWND hwnd) 777 : _hwnd(hwnd) 778 { 779 ClientRect clnt(hwnd); 780 _last_size.cx = clnt.right; 781 _last_size.cy = clnt.bottom; 782 783 WindowRect rect(hwnd); 784 _min_wnd_size.cx = rect.right - rect.left; 785 _min_wnd_size.cy = rect.bottom - rect.top; 786 } 787 788 void ResizeManager::HandleSize(int cx, int cy) 789 { 790 ClientRect clnt_rect(_hwnd); 791 SIZE new_size = {cx, cy}; 792 793 int dx = new_size.cx - _last_size.cx; 794 int dy = new_size.cy - _last_size.cy; 795 796 if (!dx && !dy) 797 return; 798 799 _last_size = new_size; 800 801 HDWP hDWP = BeginDeferWindowPos(size()); 802 803 for(ResizeManager::const_iterator it=begin(); it!=end(); ++it) { 804 const ResizeEntry& e = *it; 805 RECT move = {0}; 806 807 if (e._flags & MOVE_LEFT) 808 move.left += dx; 809 810 if (e._flags & MOVE_RIGHT) 811 move.right += dx; 812 813 if (e._flags & MOVE_TOP) 814 move.top += dy; 815 816 if (e._flags & MOVE_BOTTOM) 817 move.bottom += dy; 818 819 UINT flags = 0; 820 821 if (!move.left && !move.top) 822 flags = SWP_NOMOVE; 823 824 if (move.right==move.left && move.bottom==move.top) 825 flags |= SWP_NOSIZE; 826 827 if (flags != (SWP_NOMOVE|SWP_NOSIZE)) { 828 HWND hwnd = GetDlgItem(_hwnd, e._id); 829 830 if (hwnd) { 831 WindowRect rect(hwnd); 832 ScreenToClient(_hwnd, rect); 833 834 rect.left += move.left; 835 rect.right += move.right; 836 rect.top += move.top; 837 rect.bottom += move.bottom; 838 839 hDWP = DeferWindowPos(hDWP, hwnd, 0, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, flags|SWP_NOACTIVATE|SWP_NOZORDER); 840 } 841 } 842 } 843 844 EndDeferWindowPos(hDWP); 845 } 846 847 void ResizeManager::Resize(int dx, int dy) 848 { 849 ::SetWindowPos(_hwnd, 0, 0, 0, _min_wnd_size.cx+dx, _min_wnd_size.cy+dy, SWP_NOMOVE|SWP_NOACTIVATE); 850 MoveVisible(_hwnd); 851 852 ClientRect clnt_rect(_hwnd); 853 HandleSize(clnt_rect.right, clnt_rect.bottom); 854 } 855 856 857 Button::Button(HWND parent, LPCTSTR title, int left, int top, int width, int height, 858 int id, DWORD flags, DWORD exStyle) 859 : WindowHandle(CreateWindowEx(exStyle, TEXT("BUTTON"), title, flags, left, top, width, height, 860 parent, (HMENU)id, g_Globals._hInstance, 0)) 861 { 862 } 863 864 865 LRESULT OwnerdrawnButton::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 866 { 867 if (nmsg == PM_DISPATCH_DRAWITEM) { 868 DrawItem((LPDRAWITEMSTRUCT)lparam); 869 return TRUE; 870 } else 871 return super::WndProc(nmsg, wparam, lparam); 872 } 873 874 875 Static::Static(HWND parent, LPCTSTR title, int left, int top, int width, int height, 876 int id, DWORD flags, DWORD exStyle) 877 : WindowHandle(CreateWindowEx(exStyle, TEXT("STATIC"), title, flags, left, top, width, height, 878 parent, (HMENU)id, g_Globals._hInstance, 0)) 879 { 880 } 881 882 883 static RECT s_MyDrawText_Rect = {0, 0, 0, 0}; 884 885 static BOOL CALLBACK MyDrawText(HDC hdc, LPARAM data, int cnt) 886 { 887 ::DrawText(hdc, (LPCTSTR)data, cnt, &s_MyDrawText_Rect, DT_SINGLELINE); 888 return TRUE; 889 } 890 891 void DrawGrayText(HDC hdc, LPRECT pRect, LPCTSTR title, int dt_flags) 892 { 893 COLORREF gray = GetSysColor(COLOR_GRAYTEXT); 894 895 if (gray) { 896 TextColor lcColor(hdc, GetSysColor(COLOR_BTNHIGHLIGHT)); 897 RECT shadowRect = {pRect->left+1, pRect->top+1, pRect->right+1, pRect->bottom+1}; 898 DrawText(hdc, title, -1, &shadowRect, dt_flags); 899 900 SetTextColor(hdc, gray); 901 DrawText(hdc, title, -1, pRect, dt_flags); 902 } else { 903 int old_r = pRect->right; 904 int old_b = pRect->bottom; 905 906 DrawText(hdc, title, -1, pRect, dt_flags|DT_CALCRECT); 907 908 int x = pRect->left + (old_r-pRect->right)/2; 909 int y = pRect->top + (old_b-pRect->bottom)/2; 910 int w = pRect->right-pRect->left; 911 int h = pRect->bottom-pRect->top; 912 s_MyDrawText_Rect.right = w; 913 s_MyDrawText_Rect.bottom = h; 914 915 GrayString(hdc, GetSysColorBrush(COLOR_GRAYTEXT), MyDrawText, (LPARAM)title, -1, x, y, w, h); 916 } 917 } 918 919 920 /* not yet used 921 void ColorButton::DrawItem(LPDRAWITEMSTRUCT dis) 922 { 923 UINT state = DFCS_BUTTONPUSH; 924 925 if (dis->itemState & ODS_DISABLED) 926 state |= DFCS_INACTIVE; 927 928 RECT textRect = {dis->rcItem.left+2, dis->rcItem.top+2, dis->rcItem.right-4, dis->rcItem.bottom-4}; 929 930 if (dis->itemState & ODS_SELECTED) { 931 state |= DFCS_PUSHED; 932 ++textRect.left; ++textRect.top; 933 ++textRect.right; ++textRect.bottom; 934 } 935 936 DrawFrameControl(dis->hDC, &dis->rcItem, DFC_BUTTON, state); 937 938 TCHAR title[BUFFER_LEN]; 939 GetWindowText(_hwnd, title, BUFFER_LEN); 940 941 BkMode bk_mode(dis->hDC, TRANSPARENT); 942 943 if (dis->itemState & (ODS_DISABLED|ODS_GRAYED)) 944 DrawGrayText(dis, &textRect, title, DT_SINGLELINE|DT_VCENTER|DT_CENTER); 945 else { 946 TextColor lcColor(dis->hDC, _textColor); 947 DrawText(dis->hDC, title, -1, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); 948 } 949 950 if (dis->itemState & ODS_FOCUS) { 951 RECT rect = { 952 dis->rcItem.left+3, dis->rcItem.top+3, 953 dis->rcItem.right-dis->rcItem.left-4, dis->rcItem.bottom-dis->rcItem.top-4 954 }; 955 if (dis->itemState & ODS_SELECTED) { 956 ++rect.left; ++rect.top; 957 ++rect.right; ++rect.bottom; 958 } 959 DrawFocusRect(dis->hDC, &rect); 960 } 961 } 962 */ 963 964 965 void PictureButton::DrawItem(LPDRAWITEMSTRUCT dis) 966 { 967 UINT state = DFCS_BUTTONPUSH; 968 int style = GetWindowStyle(_hwnd); 969 970 if (dis->itemState & ODS_DISABLED) 971 state |= DFCS_INACTIVE; 972 973 POINT imagePos; 974 RECT textRect; 975 int dt_flags; 976 977 if (style & BS_BOTTOM) { 978 // align horizontal centered, vertical floating 979 imagePos.x = (dis->rcItem.left + dis->rcItem.right - _cx) / 2; 980 imagePos.y = dis->rcItem.top + 3; 981 982 textRect.left = dis->rcItem.left + 2; 983 textRect.top = dis->rcItem.top + _cy + 4; 984 textRect.right = dis->rcItem.right - 4; 985 textRect.bottom = dis->rcItem.bottom - 4; 986 987 dt_flags = DT_SINGLELINE|DT_CENTER|DT_VCENTER; 988 } else { 989 // horizontal floating, vertical centered 990 imagePos.x = dis->rcItem.left + 3; 991 imagePos.y = (dis->rcItem.top + dis->rcItem.bottom - _cy)/2; 992 993 textRect.left = dis->rcItem.left + _cx + 4; 994 textRect.top = dis->rcItem.top + 2; 995 textRect.right = dis->rcItem.right - 4; 996 textRect.bottom = dis->rcItem.bottom - 4; 997 998 dt_flags = DT_SINGLELINE|DT_VCENTER/*|DT_CENTER*/; 999 } 1000 1001 if (dis->itemState & ODS_SELECTED) { 1002 state |= DFCS_PUSHED; 1003 ++imagePos.x; ++imagePos.y; 1004 ++textRect.left; ++textRect.top; 1005 ++textRect.right; ++textRect.bottom; 1006 } 1007 1008 if (_flat) { 1009 FillRect(dis->hDC, &dis->rcItem, _hBrush); 1010 1011 if (style & BS_FLAT) // Only with BS_FLAT set, there will be drawn a frame without highlight. 1012 DrawEdge(dis->hDC, &dis->rcItem, EDGE_RAISED, BF_RECT|BF_FLAT); 1013 } else 1014 DrawFrameControl(dis->hDC, &dis->rcItem, DFC_BUTTON, state); 1015 1016 if (_hIcon) 1017 DrawIconEx(dis->hDC, imagePos.x, imagePos.y, _hIcon, _cx, _cy, 0, _hBrush, DI_NORMAL); 1018 else { 1019 MemCanvas mem_dc; 1020 BitmapSelection sel(mem_dc, _hBmp); 1021 BitBlt(dis->hDC, imagePos.x, imagePos.y, _cx, _cy, mem_dc, 0, 0, SRCCOPY); 1022 } 1023 1024 TCHAR title[BUFFER_LEN]; 1025 GetWindowText(_hwnd, title, BUFFER_LEN); 1026 1027 BkMode bk_mode(dis->hDC, TRANSPARENT); 1028 1029 if (dis->itemState & (ODS_DISABLED|ODS_GRAYED)) 1030 DrawGrayText(dis->hDC, &textRect, title, dt_flags); 1031 else { 1032 TextColor lcColor(dis->hDC, GetSysColor(COLOR_BTNTEXT)); 1033 DrawText(dis->hDC, title, -1, &textRect, dt_flags); 1034 } 1035 1036 if (dis->itemState & ODS_FOCUS) { 1037 RECT rect = { 1038 dis->rcItem.left+3, dis->rcItem.top+3, 1039 dis->rcItem.right-dis->rcItem.left-4, dis->rcItem.bottom-dis->rcItem.top-4 1040 }; 1041 if (dis->itemState & ODS_SELECTED) { 1042 ++rect.left; ++rect.top; 1043 ++rect.right; ++rect.bottom; 1044 } 1045 DrawFocusRect(dis->hDC, &rect); 1046 } 1047 } 1048 1049 1050 void FlatButton::DrawItem(LPDRAWITEMSTRUCT dis) 1051 { 1052 UINT style = DFCS_BUTTONPUSH; 1053 1054 if (dis->itemState & ODS_DISABLED) 1055 style |= DFCS_INACTIVE; 1056 1057 RECT textRect = {dis->rcItem.left+2, dis->rcItem.top+2, dis->rcItem.right-4, dis->rcItem.bottom-4}; 1058 1059 if (dis->itemState & ODS_SELECTED) { 1060 style |= DFCS_PUSHED; 1061 ++textRect.left; ++textRect.top; 1062 ++textRect.right; ++textRect.bottom; 1063 } 1064 1065 FillRect(dis->hDC, &dis->rcItem, GetSysColorBrush(COLOR_BTNFACE)); 1066 1067 // highlight the button? 1068 if (_active) 1069 DrawEdge(dis->hDC, &dis->rcItem, EDGE_ETCHED, BF_RECT); 1070 else if (GetWindowStyle(_hwnd) & BS_FLAT) // Only with BS_FLAT there will be drawn a frame to show highlighting. 1071 DrawEdge(dis->hDC, &dis->rcItem, EDGE_RAISED, BF_RECT|BF_FLAT); 1072 1073 TCHAR txt[BUFFER_LEN]; 1074 int txt_len = GetWindowText(_hwnd, txt, BUFFER_LEN); 1075 1076 if (dis->itemState & (ODS_DISABLED|ODS_GRAYED)) { 1077 COLORREF gray = GetSysColor(COLOR_GRAYTEXT); 1078 1079 if (gray) { 1080 { 1081 TextColor lcColor(dis->hDC, GetSysColor(COLOR_BTNHIGHLIGHT)); 1082 RECT shadowRect = {textRect.left+1, textRect.top+1, textRect.right+1, textRect.bottom+1}; 1083 DrawText(dis->hDC, txt, txt_len, &shadowRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); 1084 } 1085 1086 BkMode mode(dis->hDC, TRANSPARENT); 1087 TextColor lcColor(dis->hDC, gray); 1088 DrawText(dis->hDC, txt, txt_len, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); 1089 } else { 1090 int old_r = textRect.right; 1091 int old_b = textRect.bottom; 1092 DrawText(dis->hDC, txt, txt_len, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER|DT_CALCRECT); 1093 int x = textRect.left + (old_r-textRect.right)/2; 1094 int y = textRect.top + (old_b-textRect.bottom)/2; 1095 int w = textRect.right-textRect.left; 1096 int h = textRect.bottom-textRect.top; 1097 s_MyDrawText_Rect.right = w; 1098 s_MyDrawText_Rect.bottom = h; 1099 GrayString(dis->hDC, GetSysColorBrush(COLOR_GRAYTEXT), MyDrawText, (LPARAM)txt, txt_len, x, y, w, h); 1100 } 1101 } else { 1102 TextColor lcColor(dis->hDC, _active? _activeColor: _textColor); 1103 DrawText(dis->hDC, txt, txt_len, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); 1104 } 1105 1106 if (dis->itemState & ODS_FOCUS) { 1107 RECT rect = { 1108 dis->rcItem.left+3, dis->rcItem.top+3, 1109 dis->rcItem.right-dis->rcItem.left-4, dis->rcItem.bottom-dis->rcItem.top-4 1110 }; 1111 if (dis->itemState & ODS_SELECTED) { 1112 ++rect.left; ++rect.top; 1113 ++rect.right; ++rect.bottom; 1114 } 1115 DrawFocusRect(dis->hDC, &rect); 1116 } 1117 } 1118 1119 LRESULT FlatButton::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 1120 { 1121 switch(nmsg) { 1122 case WM_MOUSEMOVE: { 1123 bool active = false; 1124 1125 if (IsWindowEnabled(_hwnd)) { 1126 DWORD pid_foreground; 1127 HWND hwnd_foreground = GetForegroundWindow(); //@@ may be better look for WM_ACTIVATEAPP ? 1128 GetWindowThreadProcessId(hwnd_foreground, &pid_foreground); 1129 1130 if (GetCurrentProcessId() == pid_foreground) { 1131 POINT pt = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)}; 1132 ClientRect clntRect(_hwnd); 1133 1134 // highlight the button? 1135 if (pt.x>=clntRect.left && pt.x<clntRect.right && pt.y>=clntRect.top && pt.y<clntRect.bottom) 1136 active = true; 1137 } 1138 } 1139 1140 if (active != _active) { 1141 _active = active; 1142 1143 if (active) { 1144 TRACKMOUSEEVENT tme = {sizeof(tme), /*TME_HOVER|*/TME_LEAVE, _hwnd/*, HOVER_DEFAULT*/}; 1145 _TrackMouseEvent(&tme); 1146 } 1147 1148 InvalidateRect(_hwnd, NULL, TRUE); 1149 } 1150 1151 return 0;} 1152 1153 case WM_LBUTTONUP: { 1154 POINT pt = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)}; 1155 ClientRect clntRect(_hwnd); 1156 1157 // no more in the active rectangle? 1158 if (pt.x<clntRect.left || pt.x>=clntRect.right || pt.y<clntRect.top || pt.y>=clntRect.bottom) 1159 goto cancel_press; 1160 1161 goto def;} 1162 1163 case WM_CANCELMODE: 1164 cancel_press: { 1165 TRACKMOUSEEVENT tme = {sizeof(tme), /*TME_HOVER|*/TME_LEAVE|TME_CANCEL, _hwnd/*, HOVER_DEFAULT*/}; 1166 _TrackMouseEvent(&tme); 1167 _active = false; 1168 ReleaseCapture();} 1169 // fall through 1170 1171 case WM_MOUSELEAVE: 1172 if (_active) { 1173 _active = false; 1174 1175 InvalidateRect(_hwnd, NULL, TRUE); 1176 } 1177 1178 return 0; 1179 1180 default: def: 1181 return super::WndProc(nmsg, wparam, lparam); 1182 } 1183 } 1184 1185 1186 HyperlinkCtrl::HyperlinkCtrl(HWND hwnd, COLORREF colorLink, COLORREF colorVisited) 1187 : super(hwnd), 1188 _cmd(ResString(GetDlgCtrlID(hwnd))), 1189 _textColor(colorLink), 1190 _colorVisited(colorVisited), 1191 _hfont(0), 1192 _crsr_link(0) 1193 { 1194 init(); 1195 } 1196 1197 HyperlinkCtrl::HyperlinkCtrl(HWND owner, int id, COLORREF colorLink, COLORREF colorVisited) 1198 : super(GetDlgItem(owner, id)), 1199 _cmd(ResString(id)), 1200 _textColor(colorLink), 1201 _colorVisited(colorVisited), 1202 _hfont(0), 1203 _crsr_link(0) 1204 { 1205 init(); 1206 } 1207 1208 void HyperlinkCtrl::init() 1209 { 1210 if (_cmd.empty()) { 1211 TCHAR txt[BUFFER_LEN]; 1212 _cmd.assign(txt, GetWindowText(_hwnd, txt, BUFFER_LEN)); 1213 } 1214 } 1215 1216 HyperlinkCtrl::~HyperlinkCtrl() 1217 { 1218 if (_hfont) 1219 DeleteObject(_hfont); 1220 } 1221 1222 LRESULT HyperlinkCtrl::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 1223 { 1224 switch(nmsg) { 1225 case PM_DISPATCH_CTLCOLOR: { 1226 if (!_hfont) { 1227 HFONT hfont = (HFONT) SendMessage(_hwnd, WM_GETFONT, 0, 0); 1228 LOGFONT lf; GetObject(hfont, sizeof(lf), &lf); 1229 lf.lfUnderline = TRUE; 1230 _hfont = CreateFontIndirect(&lf); 1231 } 1232 1233 HDC hdc = (HDC) wparam; 1234 SetTextColor(hdc, _textColor); //@@ 1235 SelectFont(hdc, _hfont); 1236 SetBkMode(hdc, TRANSPARENT); 1237 return (LRESULT)GetStockObject(HOLLOW_BRUSH); 1238 } 1239 1240 case WM_SETCURSOR: 1241 if (!_crsr_link) 1242 _crsr_link = LoadCursor(0, IDC_HAND); 1243 1244 if (_crsr_link) 1245 SetCursor(_crsr_link); 1246 return 0; 1247 1248 case WM_NCHITTEST: 1249 return HTCLIENT; // Aktivierung von Maus-Botschaften 1250 1251 case WM_LBUTTONDOWN: 1252 if (LaunchLink()) { 1253 _textColor = _colorVisited; 1254 InvalidateRect(_hwnd, NULL, FALSE); 1255 } else 1256 MessageBeep(0); 1257 return 0; 1258 1259 default: 1260 return super::WndProc(nmsg, wparam, lparam); 1261 } 1262 } 1263 1264 1265 ToolTip::ToolTip(HWND owner) 1266 : super(CreateWindowEx(WS_EX_TOPMOST|WS_EX_NOPARENTNOTIFY, TOOLTIPS_CLASS, 0, 1267 WS_POPUP|TTS_NOPREFIX|TTS_ALWAYSTIP, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, 1268 owner, 0, g_Globals._hInstance, 0)) 1269 { 1270 activate(); 1271 } 1272 1273 1274 ListSort::ListSort(HWND hwndListview, PFNLVCOMPARE compare_fct) 1275 : WindowHandle(hwndListview), 1276 _compare_fct(compare_fct) 1277 { 1278 _sort_crit = 0; 1279 _direction = false; 1280 } 1281 1282 void ListSort::toggle_sort(int idx) 1283 { 1284 if (_sort_crit == idx) 1285 _direction = !_direction; 1286 else { 1287 _sort_crit = idx; 1288 _direction = false; 1289 } 1290 } 1291 1292 void ListSort::sort() 1293 { 1294 int idx = ListView_GetSelectionMark(_hwnd); 1295 LPARAM param = ListView_GetItemData(_hwnd, idx); 1296 1297 ListView_SortItems(_hwnd, _compare_fct, (LPARAM)this); 1298 1299 if (idx >= 0) { 1300 idx = ListView_FindItemPara(_hwnd, param); 1301 ListView_EnsureVisible(_hwnd, idx, FALSE); 1302 } 1303 } 1304 1305 1306 PropSheetPage::PropSheetPage(UINT nid, Window::CREATORFUNC dlg_creator) 1307 : _dlg_creator(dlg_creator) 1308 { 1309 PROPSHEETPAGE::dwSize = sizeof(PROPSHEETPAGE); 1310 PROPSHEETPAGE::dwFlags = 0; 1311 PROPSHEETPAGE::hInstance = g_Globals._hInstance; 1312 PROPSHEETPAGE::pszTemplate = MAKEINTRESOURCE(nid); 1313 PROPSHEETPAGE::pfnDlgProc = PropSheetPageDlg::DialogProc; 1314 PROPSHEETPAGE::lParam = (LPARAM) this; 1315 } 1316 1317 1318 #ifndef PSM_GETRESULT // currently (as of 18.01.2004) missing in MinGW headers 1319 #define PSM_GETRESULT (WM_USER + 135) 1320 #define PropSheet_GetResult(hDlg) SNDMSG(hDlg, PSM_GETRESULT, 0, 0) 1321 #endif 1322 1323 1324 PropertySheetDialog::PropertySheetDialog(HWND owner) 1325 : _hwnd(0) 1326 { 1327 PROPSHEETHEADER::dwSize = sizeof(PROPSHEETHEADER); 1328 PROPSHEETHEADER::dwFlags = PSH_PROPSHEETPAGE | PSH_MODELESS; 1329 PROPSHEETHEADER::hwndParent = owner; 1330 PROPSHEETHEADER::hInstance = g_Globals._hInstance; 1331 } 1332 1333 void PropertySheetDialog::add(PropSheetPage& psp) 1334 { 1335 _pages.push_back(psp); 1336 } 1337 1338 int PropertySheetDialog::DoModal(int start_page) 1339 { 1340 PROPSHEETHEADER::ppsp = (LPCPROPSHEETPAGE) &_pages[0]; 1341 PROPSHEETHEADER::nPages = _pages.size(); 1342 PROPSHEETHEADER::nStartPage = start_page; 1343 /* 1344 Window* pwnd = Window::create_property_sheet(this, WINDOW_CREATOR(PropertySheetDlg), NULL); 1345 if (!pwnd) 1346 return -1; 1347 1348 HWND hwndPropSheet = *pwnd; 1349 */ 1350 int ret = PropertySheet(this); 1351 if (ret == -1) 1352 return -1; 1353 1354 HWND hwndPropSheet = (HWND) ret; 1355 HWND hwndparent = GetParent(hwndPropSheet); 1356 1357 if (hwndparent) 1358 EnableWindow(hwndparent, FALSE); 1359 1360 ret = 0; 1361 MSG msg; 1362 1363 while(GetMessage(&msg, 0, 0, 0)) { 1364 try { 1365 if (Window::pretranslate_msg(&msg)) 1366 continue; 1367 1368 if (PropSheet_IsDialogMessage(hwndPropSheet, &msg)) 1369 continue; 1370 1371 if (Window::dispatch_dialog_msg(&msg)) 1372 continue; 1373 1374 TranslateMessage(&msg); 1375 1376 try { 1377 DispatchMessage(&msg); 1378 } catch(COMException& e) { 1379 HandleException(e, 0); 1380 } 1381 1382 if (!PropSheet_GetCurrentPageHwnd(hwndPropSheet)) { 1383 ret = PropSheet_GetResult(hwndPropSheet); 1384 break; 1385 } 1386 } catch(COMException& e) { 1387 HandleException(e, 0); 1388 } 1389 } 1390 1391 if (hwndparent) 1392 EnableWindow(hwndparent, TRUE); 1393 1394 DestroyWindow(hwndPropSheet); 1395 1396 return ret; 1397 } 1398 1399 HWND PropertySheetDialog::GetCurrentPage() 1400 { 1401 HWND hdlg = PropSheet_GetCurrentPageHwnd(_hwnd); 1402 return hdlg; 1403 } 1404 1405 1406 PropSheetPageDlg::PropSheetPageDlg(HWND hwnd) 1407 : super(hwnd) 1408 { 1409 } 1410 1411 INT_PTR CALLBACK PropSheetPageDlg::DialogProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) 1412 { 1413 PropSheetPageDlg* pThis = GET_WINDOW(PropSheetPageDlg, hwnd); 1414 1415 if (pThis) { 1416 switch(nmsg) { 1417 case WM_COMMAND: 1418 pThis->Command(LOWORD(wparam), HIWORD(wparam)); 1419 return TRUE; // message has been processed 1420 1421 case WM_NOTIFY: 1422 pThis->Notify(wparam, (NMHDR*)lparam); 1423 return TRUE; // message has been processed 1424 1425 case WM_NOTIFYFORMAT: 1426 SetWindowLongPtr(hwnd, DWLP_MSGRESULT, NFR_CURRENT); // set return value NFR_CURRENT 1427 return TRUE; // message has been processed 1428 1429 case WM_NCDESTROY: 1430 delete pThis; 1431 return TRUE; // message has been processed 1432 1433 default: 1434 return pThis->WndProc(nmsg, wparam, lparam); 1435 } 1436 } else if (nmsg == WM_INITDIALOG) { 1437 PROPSHEETPAGE* psp = (PROPSHEETPAGE*) lparam; 1438 PropSheetPage* ppsp = (PropSheetPage*) psp->lParam; 1439 1440 if (ppsp->_dlg_creator) { 1441 pThis = static_cast<PropSheetPageDlg*>(ppsp->_dlg_creator(hwnd)); 1442 1443 if (pThis) 1444 return pThis->Init(NULL); 1445 } 1446 } 1447 1448 return FALSE; // message has not been processed 1449 } 1450 1451 int PropSheetPageDlg::Command(int id, int code) 1452 { 1453 // override call to EndDialog in Dialog::Command(); 1454 1455 return FALSE; 1456 } 1457