00001 /* 00002 * Copyright 2003, 2004, 2005 Martin Fuchs 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 */ 00018 00019 00020 // 00021 // Explorer clone 00022 // 00023 // window.cpp 00024 // 00025 // Martin Fuchs, 23.07.2003 00026 // 00027 00028 00029 #include <precomp.h> 00030 00031 #include "../resource.h" // for ID_GO_BACK, ... 00032 00033 00034 WindowClass::WindowClass(LPCTSTR classname, UINT style_, WNDPROC wndproc) 00035 { 00036 memset(this, 0, sizeof(WNDCLASSEX)); 00037 00038 cbSize = sizeof(WNDCLASSEX); 00039 style = style_; 00040 hInstance = g_Globals._hInstance; 00041 hCursor = LoadCursor(0, IDC_ARROW); 00042 00043 lpszClassName = classname; 00044 lpfnWndProc = wndproc; 00045 00046 _atomClass = 0; 00047 } 00048 00049 00050 IconWindowClass::IconWindowClass(LPCTSTR classname, UINT nid, UINT style, WNDPROC wndproc) 00051 : WindowClass(classname, style, wndproc) 00052 { 00053 hIcon = ResIcon(nid); 00054 hIconSm = SmallIcon(nid); 00055 } 00056 00057 00058 Window::WindowMap Window::s_wnd_map; 00059 00060 Window::CREATORFUNC Window::s_window_creator = NULL; 00061 const void* Window::s_new_info = NULL; 00062 00063 HHOOK Window::s_hcbtHook = 0; 00064 00065 00066 Window::StaticWindowData& Window::GetStaticWindowData() 00067 { 00068 static StaticWindowData s_initialized_data; 00069 00070 return s_initialized_data; 00071 } 00072 00073 00074 Window::Window(HWND hwnd) 00075 : WindowHandle(hwnd) 00076 { 00077 Lock lock(GetStaticWindowData()._map_crit_sect); // protect access to s_wnd_map 00078 00079 s_wnd_map[_hwnd] = this; 00080 } 00081 00082 Window::~Window() 00083 { 00084 Lock lock(GetStaticWindowData()._map_crit_sect); // protect access to s_wnd_map 00085 00086 s_wnd_map.erase(_hwnd); 00087 } 00088 00089 00090 HWND Window::Create(CREATORFUNC creator, DWORD dwExStyle, 00091 LPCTSTR lpClassName, LPCTSTR lpWindowName, 00092 DWORD dwStyle, int x, int y, int w, int h, 00093 HWND hwndParent, HMENU hMenu/*, LPVOID lpParam*/) 00094 { 00095 Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info 00096 00097 s_window_creator = creator; 00098 s_new_info = NULL; 00099 00100 return CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, 00101 x, y, w, h, 00102 hwndParent, hMenu, g_Globals._hInstance, 0/*lpParam*/); 00103 } 00104 00105 HWND Window::Create(CREATORFUNC_INFO creator, const void* info, DWORD dwExStyle, 00106 LPCTSTR lpClassName, LPCTSTR lpWindowName, 00107 DWORD dwStyle, int x, int y, int w, int h, 00108 HWND hwndParent, HMENU hMenu/*, LPVOID lpParam*/) 00109 { 00110 Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info 00111 00112 s_window_creator = (CREATORFUNC) creator; 00113 s_new_info = info; 00114 00115 return CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, 00116 x, y, w, h, 00117 hwndParent, hMenu, g_Globals._hInstance, 0/*lpParam*/); 00118 } 00119 00120 00121 Window* Window::create_mdi_child(const ChildWndInfo& info, const MDICREATESTRUCT& mcs, CREATORFUNC_INFO creator) 00122 { 00123 Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info 00124 00125 s_window_creator = (CREATORFUNC) creator; 00126 s_new_info = &info; 00127 00128 s_hcbtHook = SetWindowsHookEx(WH_CBT, MDICBTHookProc, 0, GetCurrentThreadId()); 00129 00130 HWND hwnd = (HWND) SendMessage(info._hmdiclient, WM_MDICREATE, 0, (LPARAM)&mcs); 00131 00132 // end hook in case it's not already done 00133 if (s_hcbtHook) 00134 UnhookWindowsHookEx(s_hcbtHook); 00135 00136 Window* child = get_window(hwnd); 00137 s_new_info = NULL; 00138 00139 if (child && (!hwnd || !child->_hwnd)) 00140 child = NULL; 00141 00142 return child; 00143 } 00144 00145 LRESULT CALLBACK Window::MDICBTHookProc(int code, WPARAM wparam, LPARAM lparam) 00146 { 00147 if (code == HCBT_CREATEWND) { 00148 UnhookWindowsHookEx(s_hcbtHook); // use the hook only for the first created window 00149 s_hcbtHook = 0; 00150 00151 HWND hwnd = (HWND)wparam; 00152 00153 // create Window controller and associate it with the window handle 00154 Window* child = get_window(hwnd); 00155 00156 if (!child) 00157 child = create_controller(hwnd); 00158 } 00159 00160 return CallNextHookEx(s_hcbtHook, code, wparam, lparam); 00161 } 00162 00163 00164 /* 00165 Window* Window::create_property_sheet(PropertySheetDialog* ppsd, CREATORFUNC creator, const void* info) 00166 { 00167 Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info 00168 00169 s_window_creator = creator; 00170 s_new_info = info; 00171 00172 s_hcbtHook = SetWindowsHookEx(WH_CBT, PropSheetCBTHookProc, 0, GetCurrentThreadId()); 00173 00174 HWND hwnd = (HWND) PropertySheet(ppsd); 00175 00176 UnhookWindowsHookEx(s_hcbtHook); 00177 00178 Window* child = get_window(hwnd); 00179 s_new_info = NULL; 00180 00181 if (child && (!hwnd || !child->_hwnd)) 00182 child = NULL; 00183 00184 return child; 00185 } 00186 */ 00187 00188 LRESULT CALLBACK Window::PropSheetCBTHookProc(int code, WPARAM wparam, LPARAM lparam) 00189 { 00190 if (code == HCBT_CREATEWND) { 00191 HWND hwnd = (HWND)wparam; 00192 00193 // create Window controller and associate it with the window handle 00194 Window* child = get_window(hwnd); 00195 00196 if (!child) 00197 child = create_controller(hwnd); 00198 } 00199 00200 return CallNextHookEx(s_hcbtHook, code, wparam, lparam); 00201 } 00202 00203 00204 /// get window controller from window handle 00205 00206 Window* Window::get_window(HWND hwnd) 00207 { 00208 { 00209 Lock lock(GetStaticWindowData()._map_crit_sect); // protect access to s_wnd_map 00210 00211 WindowMap::const_iterator found = s_wnd_map.find(hwnd); 00212 00213 if (found!=s_wnd_map.end()) 00214 return found->second; 00215 } 00216 00217 return NULL; 00218 } 00219 00220 00221 /// create controller for a new window 00222 00223 Window* Window::create_controller(HWND hwnd) 00224 { 00225 if (s_window_creator) { // protect for recursion and create the window object only for the first window 00226 Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info 00227 00228 const void* info = s_new_info; 00229 s_new_info = NULL; 00230 00231 CREATORFUNC window_creator = s_window_creator; 00232 s_window_creator = NULL; 00233 00234 if (info) 00235 return CREATORFUNC_INFO(window_creator)(hwnd, info); 00236 else 00237 return CREATORFUNC(window_creator)(hwnd); 00238 } 00239 00240 return NULL; 00241 } 00242 00243 00244 LRESULT Window::Init(LPCREATESTRUCT pcs) 00245 { 00246 return 0; 00247 } 00248 00249 00250 LRESULT CALLBACK Window::WindowWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) 00251 { 00252 Window* pThis = get_window(hwnd); 00253 00254 if (!pThis) 00255 pThis = create_controller(hwnd); 00256 00257 if (pThis) { 00258 switch(nmsg) { 00259 case WM_COMMAND: 00260 return pThis->Command(LOWORD(wparam), HIWORD(wparam)); 00261 00262 case WM_NOTIFY: 00263 return pThis->Notify(wparam, (NMHDR*)lparam); 00264 00265 case WM_NOTIFYFORMAT: 00266 return NFR_CURRENT; 00267 00268 case WM_CREATE: 00269 return pThis->Init((LPCREATESTRUCT)lparam); 00270 00271 case WM_NCDESTROY: 00272 delete pThis; 00273 return 0; 00274 00275 default: 00276 return pThis->WndProc(nmsg, wparam, lparam); 00277 } 00278 } 00279 else 00280 return DefWindowProc(hwnd, nmsg, wparam, lparam); 00281 } 00282 00283 LRESULT Window::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 00284 { 00285 return DefWindowProc(_hwnd, nmsg, wparam, lparam); 00286 } 00287 00288 int Window::Command(int id, int code) 00289 { 00290 return 1; // no command handler found 00291 } 00292 00293 int Window::Notify(int id, NMHDR* pnmh) 00294 { 00295 return 0; 00296 } 00297 00298 void Window::CancelModes() 00299 { 00300 PostMessage(HWND_BROADCAST, WM_CANCELMODE, 0, 0); 00301 } 00302 00303 00304 SubclassedWindow::SubclassedWindow(HWND hwnd) 00305 : super(hwnd) 00306 { 00307 _orgWndProc = SubclassWindow(_hwnd, SubclassedWndProc); 00308 00309 if (!_orgWndProc) 00310 delete this; 00311 } 00312 00313 LRESULT CALLBACK SubclassedWindow::SubclassedWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) 00314 { 00315 SubclassedWindow* pThis = GET_WINDOW(SubclassedWindow, hwnd); 00316 assert(pThis); 00317 00318 if (pThis) { 00319 switch(nmsg) { 00320 case WM_COMMAND: 00321 if (!pThis->Command(LOWORD(wparam), HIWORD(wparam))) 00322 return 0; 00323 break; 00324 00325 case WM_NOTIFY: 00326 return pThis->Notify(wparam, (NMHDR*)lparam); 00327 00328 case WM_NOTIFYFORMAT: 00329 return NFR_CURRENT; 00330 00331 case WM_CREATE: 00332 return pThis->Init((LPCREATESTRUCT)lparam); 00333 00334 case WM_NCDESTROY: 00335 delete pThis; 00336 return 0; 00337 00338 default: 00339 return pThis->WndProc(nmsg, wparam, lparam); 00340 } 00341 } 00342 00343 return CallWindowProc(pThis->_orgWndProc, hwnd, nmsg, wparam, lparam); 00344 } 00345 00346 LRESULT SubclassedWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 00347 { 00348 return CallWindowProc(_orgWndProc, _hwnd, nmsg, wparam, lparam); 00349 } 00350 00351 int SubclassedWindow::Command(int id, int code) 00352 { 00353 return 1; // no command handler found 00354 } 00355 00356 int SubclassedWindow::Notify(int id, NMHDR* pnmh) 00357 { 00358 return CallWindowProc(_orgWndProc, _hwnd, WM_NOTIFY, id, (LPARAM)pnmh); 00359 } 00360 00361 00362 ChildWindow::ChildWindow(HWND hwnd, const ChildWndInfo& info) 00363 : super(hwnd), 00364 _hwndFrame(GetParent(info._hmdiclient)) 00365 { 00366 _focus_pane = 0; 00367 _split_pos = DEFAULT_SPLIT_POS; 00368 _last_split = DEFAULT_SPLIT_POS; 00369 } 00370 00371 00372 ChildWindow* ChildWindow::create(const ChildWndInfo& info, const RECT& rect, CREATORFUNC_INFO creator, 00373 LPCTSTR classname, LPCTSTR title, DWORD style) 00374 { 00375 MDICREATESTRUCT mcs; 00376 00377 mcs.szClass = classname; 00378 mcs.szTitle = title; 00379 mcs.hOwner = g_Globals._hInstance; 00380 mcs.x = rect.left, 00381 mcs.y = rect.top; 00382 mcs.cx = rect.right - rect.left; 00383 mcs.cy = rect.bottom - rect.top; 00384 mcs.style = style; 00385 mcs.lParam = 0; 00386 00387 return static_cast<ChildWindow*>(create_mdi_child(info, mcs, creator)); 00388 } 00389 00390 00391 LRESULT ChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 00392 { 00393 switch(nmsg) { 00394 case WM_PAINT: { 00395 RECT rc; 00396 PaintCanvas canvas(_hwnd); 00397 ClientRect rt(_hwnd); 00398 rt.left = _split_pos-SPLIT_WIDTH/2; 00399 rt.right = _split_pos+SPLIT_WIDTH/2+1; 00400 HBRUSH lastBrush = SelectBrush(canvas, GetStockBrush(COLOR_SPLITBAR)); 00401 Rectangle(canvas, rt.left, rt.top-1, rt.right, rt.bottom+1); 00402 SetRect(&rc, rt.left, rt.top-1, rt.right, rt.bottom+1); 00403 DrawEdge(canvas, &rc, EDGE_RAISED, BF_RECT); 00404 SelectObject(canvas, lastBrush); 00405 break;} 00406 00407 case WM_SETCURSOR: 00408 if (LOWORD(lparam) == HTCLIENT) { 00409 POINT pt; 00410 GetCursorPos(&pt); 00411 ScreenToClient(_hwnd, &pt); 00412 00413 if (pt.x>=_split_pos-SPLIT_WIDTH/2 && pt.x<_split_pos+SPLIT_WIDTH/2+1) { 00414 SetCursor(LoadCursor(0, IDC_SIZEWE)); 00415 return TRUE; 00416 } 00417 } 00418 goto def; 00419 00420 case WM_SIZE: 00421 if (wparam != SIZE_MINIMIZED) 00422 resize_children(LOWORD(lparam), HIWORD(lparam)); 00423 goto def; 00424 00425 case WM_GETMINMAXINFO: 00426 DefMDIChildProc(_hwnd, nmsg, wparam, lparam); 00427 00428 {LPMINMAXINFO lpmmi = (LPMINMAXINFO)lparam; 00429 00430 lpmmi->ptMaxTrackSize.x <<= 1; // 2*GetSystemMetrics(SM_CXSCREEN) / SM_CXVIRTUALSCREEN 00431 lpmmi->ptMaxTrackSize.y <<= 1; // 2*GetSystemMetrics(SM_CYSCREEN) / SM_CYVIRTUALSCREEN 00432 break;} 00433 00434 case WM_LBUTTONDOWN: { 00435 int x = GET_X_LPARAM(lparam); 00436 00437 ClientRect rt(_hwnd); 00438 00439 if (x>=_split_pos-SPLIT_WIDTH/2 && x<_split_pos+SPLIT_WIDTH/2+1) { 00440 _last_split = _split_pos; 00441 SetCapture(_hwnd); 00442 } 00443 00444 break;} 00445 00446 case WM_LBUTTONUP: 00447 if (GetCapture() == _hwnd) 00448 ReleaseCapture(); 00449 break; 00450 00451 case WM_KEYDOWN: 00452 if (wparam == VK_ESCAPE) 00453 if (GetCapture() == _hwnd) { 00454 _split_pos = _last_split; 00455 ClientRect rt(_hwnd); 00456 resize_children(rt.right, rt.bottom); 00457 _last_split = -1; 00458 ReleaseCapture(); 00459 SetCursor(LoadCursor(0, IDC_ARROW)); 00460 } 00461 break; 00462 00463 case WM_MOUSEMOVE: 00464 if (GetCapture() == _hwnd) { 00465 int x = GET_X_LPARAM(lparam); 00466 00467 ClientRect rt(_hwnd); 00468 00469 if (x>=0 && x<rt.right) { 00470 _split_pos = x; 00471 resize_children(rt.right, rt.bottom); 00472 rt.left = x-SPLIT_WIDTH/2; 00473 rt.right = x+SPLIT_WIDTH/2+1; 00474 InvalidateRect(_hwnd, &rt, FALSE); 00475 UpdateWindow(_left_hwnd); 00476 UpdateWindow(_hwnd); 00477 UpdateWindow(_right_hwnd); 00478 } 00479 } 00480 break; 00481 00482 case PM_DISPATCH_COMMAND: 00483 switch(LOWORD(wparam)) { 00484 case ID_GO_BACK: 00485 if (!_url_history.empty()) { 00486 const String& url = jump_to_int(_url_history.top()); 00487 00488 if (jump_to_int(url)) 00489 set_url(url); 00490 00491 _url_history.pop(); 00492 } 00493 break; 00494 00495 case ID_GO_FORWARD: 00496 //@@ 00497 break; 00498 00499 case ID_GO_UP: 00500 ///@todo 00501 break; 00502 00503 case ID_GO_HOME: 00504 //@@ 00505 break; 00506 00507 default: 00508 return FALSE; 00509 } 00510 return TRUE; 00511 00512 case WM_MDIACTIVATE: 00513 if ((HWND)lparam == _hwnd) { 00514 SendMessage(_hwndFrame, PM_SETSTATUSTEXT, 0, (LPARAM)_statusText.c_str()); 00515 SendMessage(_hwndFrame, PM_URL_CHANGED, 0, (LPARAM)_url.c_str()); 00516 } 00517 break; 00518 00519 case PM_JUMP_TO_URL: 00520 return go_to((LPCTSTR)lparam)? TRUE: FALSE; 00521 00522 default: def: 00523 return DefMDIChildProc(_hwnd, nmsg, wparam, lparam); 00524 } 00525 00526 return 0; 00527 } 00528 00529 00530 void ChildWindow::resize_children(int cx, int cy) 00531 { 00532 HDWP hdwp = BeginDeferWindowPos(2); 00533 RECT rt; 00534 00535 rt.left = 0; 00536 rt.top = 0; 00537 rt.right = cx; 00538 rt.bottom = cy; 00539 00540 if (_left_hwnd) { 00541 cx = _split_pos + SPLIT_WIDTH/2; 00542 00543 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); 00544 } else { 00545 _split_pos = 0; 00546 cx = 0; 00547 } 00548 00549 if (_right_hwnd) 00550 hdwp = DeferWindowPos(hdwp, _right_hwnd, 0, rt.left+cx+1, rt.top, rt.right-cx, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE); 00551 00552 EndDeferWindowPos(hdwp); 00553 } 00554 00555 00556 bool ChildWindow::go_to(LPCTSTR url) 00557 { 00558 const String& url_str = jump_to_int(url); 00559 00560 if (!url_str.empty()) { 00561 set_url(url_str); 00562 00563 _url_history.push(url_str); 00564 00565 return true; 00566 } else 00567 return false; 00568 } 00569 00570 void ChildWindow::set_url(LPCTSTR url) 00571 { 00572 if (_url != url) { 00573 _url = url; 00574 00575 SendMessage(_hwndFrame, PM_URL_CHANGED, 0, (LPARAM)url); 00576 } 00577 } 00578 00579 00580 WindowSet Window::s_pretranslate_windows; 00581 00582 void Window::register_pretranslate(HWND hwnd) 00583 { 00584 s_pretranslate_windows.insert(hwnd); 00585 } 00586 00587 void Window::unregister_pretranslate(HWND hwnd) 00588 { 00589 s_pretranslate_windows.erase(hwnd); 00590 } 00591 00592 BOOL Window::pretranslate_msg(LPMSG pmsg) 00593 { 00594 for(WindowSet::const_iterator it=Window::s_pretranslate_windows.begin(); it!=s_pretranslate_windows.end(); ++it) 00595 if (SendMessage(*it, PM_TRANSLATE_MSG, 0, (LPARAM)pmsg)) 00596 return TRUE; 00597 00598 return FALSE; 00599 } 00600 00601 00602 WindowSet Window::s_dialogs; 00603 00604 void Window::register_dialog(HWND hwnd) 00605 { 00606 s_dialogs.insert(hwnd); 00607 } 00608 00609 void Window::unregister_dialog(HWND hwnd) 00610 { 00611 s_dialogs.erase(hwnd); 00612 } 00613 00614 BOOL Window::dispatch_dialog_msg(MSG* pmsg) 00615 { 00616 for(WindowSet::const_iterator it=Window::s_dialogs.begin(); it!=s_dialogs.end(); ++it) 00617 if (IsDialogMessage(*it, pmsg)) 00618 return TRUE; 00619 00620 return FALSE; 00621 } 00622 00623 00624 int Window::MessageLoop() 00625 { 00626 MSG msg; 00627 00628 while(GetMessage(&msg, 0, 0, 0)) { 00629 try { 00630 if (pretranslate_msg(&msg)) 00631 continue; 00632 00633 if (dispatch_dialog_msg(&msg)) 00634 continue; 00635 00636 TranslateMessage(&msg); 00637 00638 try { 00639 DispatchMessage(&msg); 00640 } catch(COMException& e) { 00641 HandleException(e, 0); 00642 } 00643 } catch(COMException& e) { 00644 HandleException(e, 0); 00645 } 00646 } 00647 00648 return msg.wParam; 00649 } 00650 00651 00652 LRESULT Window::SendParent(UINT nmsg, WPARAM wparam, LPARAM lparam) 00653 { 00654 HWND parent = GetParent(_hwnd); 00655 00656 if (!parent) 00657 return 0; 00658 00659 return SendMessage(parent, nmsg, wparam, lparam); 00660 } 00661 00662 LRESULT Window::PostParent(UINT nmsg, WPARAM wparam, LPARAM lparam) 00663 { 00664 HWND parent = GetParent(_hwnd); 00665 00666 if (!parent) 00667 return 0; 00668 00669 return PostMessage(parent, nmsg, wparam, lparam); 00670 } 00671 00672 00673 PreTranslateWindow::PreTranslateWindow(HWND hwnd) 00674 : super(hwnd) 00675 { 00676 register_pretranslate(hwnd); 00677 } 00678 00679 PreTranslateWindow::~PreTranslateWindow() 00680 { 00681 unregister_pretranslate(_hwnd); 00682 } 00683 00684 00685 Dialog::Dialog(HWND hwnd) 00686 : super(hwnd) 00687 { 00688 register_dialog(hwnd); 00689 } 00690 00691 Dialog::~Dialog() 00692 { 00693 unregister_dialog(_hwnd); 00694 } 00695 00696 int Dialog::DoModal(UINT nid, CREATORFUNC creator, HWND hwndParent) 00697 { 00698 Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info 00699 00700 s_window_creator = creator; 00701 s_new_info = NULL; 00702 00703 ///@todo call Window::pretranslate_msg() 00704 00705 return DialogBoxParam(g_Globals._hInstance, MAKEINTRESOURCE(nid), hwndParent, DialogProc, 0/*lpParam*/); 00706 } 00707 00708 int Dialog::DoModal(UINT nid, CREATORFUNC_INFO creator, const void* info, HWND hwndParent) 00709 { 00710 Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info 00711 00712 s_window_creator = (CREATORFUNC) creator; 00713 s_new_info = NULL; 00714 00715 ///@todo call Window::pretranslate_msg() 00716 00717 return DialogBoxParam(g_Globals._hInstance, MAKEINTRESOURCE(nid), hwndParent, DialogProc, 0/*lpParam*/); 00718 } 00719 00720 INT_PTR CALLBACK Window::DialogProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) 00721 { 00722 Window* pThis = get_window(hwnd); 00723 00724 if (pThis) { 00725 switch(nmsg) { 00726 case WM_COMMAND: 00727 pThis->Command(LOWORD(wparam), HIWORD(wparam)); 00728 return TRUE; // message has been processed 00729 00730 case WM_NOTIFY: 00731 pThis->Notify(wparam, (NMHDR*)lparam); 00732 return TRUE; // message has been processed 00733 00734 case WM_NOTIFYFORMAT: 00735 SetWindowLong(hwnd, DWLP_MSGRESULT, NFR_CURRENT); // set return value NFR_CURRENT 00736 return TRUE; // message has been processed 00737 00738 case WM_NCDESTROY: 00739 delete pThis; 00740 return TRUE; // message has been processed 00741 00742 default: 00743 return pThis->WndProc(nmsg, wparam, lparam); 00744 } 00745 } else if (nmsg == WM_INITDIALOG) { 00746 pThis = create_controller(hwnd); 00747 00748 if (pThis) 00749 return pThis->Init(NULL); 00750 } 00751 00752 return FALSE; // message has not been processed 00753 } 00754 00755 LRESULT Dialog::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 00756 { 00757 return FALSE; // message has not been processed 00758 } 00759 00760 int Dialog::Command(int id, int code) 00761 { 00762 if (code == BN_CLICKED) { 00763 EndDialog(_hwnd, id); 00764 return 0; // message has been processed 00765 } 00766 00767 return 1; 00768 } 00769 00770 00771 ResizeManager::ResizeManager(HWND hwnd) 00772 : _hwnd(hwnd) 00773 { 00774 ClientRect clnt(hwnd); 00775 _last_size.cx = clnt.right; 00776 _last_size.cy = clnt.bottom; 00777 00778 WindowRect rect(hwnd); 00779 _min_wnd_size.cx = rect.right - rect.left; 00780 _min_wnd_size.cy = rect.bottom - rect.top; 00781 } 00782 00783 void ResizeManager::HandleSize(int cx, int cy) 00784 { 00785 ClientRect clnt_rect(_hwnd); 00786 SIZE new_size = {cx, cy}; 00787 00788 int dx = new_size.cx - _last_size.cx; 00789 int dy = new_size.cy - _last_size.cy; 00790 00791 if (!dx && !dy) 00792 return; 00793 00794 _last_size = new_size; 00795 00796 HDWP hDWP = BeginDeferWindowPos(size()); 00797 00798 for(ResizeManager::const_iterator it=begin(); it!=end(); ++it) { 00799 const ResizeEntry& e = *it; 00800 RECT move = {0}; 00801 00802 if (e._flags & MOVE_LEFT) 00803 move.left += dx; 00804 00805 if (e._flags & MOVE_RIGHT) 00806 move.right += dx; 00807 00808 if (e._flags & MOVE_TOP) 00809 move.top += dy; 00810 00811 if (e._flags & MOVE_BOTTOM) 00812 move.bottom += dy; 00813 00814 UINT flags = 0; 00815 00816 if (!move.left && !move.top) 00817 flags = SWP_NOMOVE; 00818 00819 if (move.right==move.left && move.bottom==move.top) 00820 flags |= SWP_NOSIZE; 00821 00822 if (flags != (SWP_NOMOVE|SWP_NOSIZE)) { 00823 HWND hwnd = GetDlgItem(_hwnd, e._id); 00824 00825 if (hwnd) { 00826 WindowRect rect(hwnd); 00827 ScreenToClient(_hwnd, rect); 00828 00829 rect.left += move.left; 00830 rect.right += move.right; 00831 rect.top += move.top; 00832 rect.bottom += move.bottom; 00833 00834 hDWP = DeferWindowPos(hDWP, hwnd, 0, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, flags|SWP_NOACTIVATE|SWP_NOZORDER); 00835 } 00836 } 00837 } 00838 00839 EndDeferWindowPos(hDWP); 00840 } 00841 00842 void ResizeManager::Resize(int dx, int dy) 00843 { 00844 ::SetWindowPos(_hwnd, 0, 0, 0, _min_wnd_size.cx+dx, _min_wnd_size.cy+dy, SWP_NOMOVE|SWP_NOACTIVATE); 00845 MoveVisible(_hwnd); 00846 00847 ClientRect clnt_rect(_hwnd); 00848 HandleSize(clnt_rect.right, clnt_rect.bottom); 00849 } 00850 00851 00852 Button::Button(HWND parent, LPCTSTR title, int left, int top, int width, int height, 00853 int id, DWORD flags, DWORD exStyle) 00854 : WindowHandle(CreateWindowEx(exStyle, TEXT("BUTTON"), title, flags, left, top, width, height, 00855 parent, (HMENU)id, g_Globals._hInstance, 0)) 00856 { 00857 } 00858 00859 00860 LRESULT OwnerdrawnButton::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 00861 { 00862 if (nmsg == PM_DISPATCH_DRAWITEM) { 00863 DrawItem((LPDRAWITEMSTRUCT)lparam); 00864 return TRUE; 00865 } else 00866 return super::WndProc(nmsg, wparam, lparam); 00867 } 00868 00869 00870 Static::Static(HWND parent, LPCTSTR title, int left, int top, int width, int height, 00871 int id, DWORD flags, DWORD exStyle) 00872 : WindowHandle(CreateWindowEx(exStyle, TEXT("STATIC"), title, flags, left, top, width, height, 00873 parent, (HMENU)id, g_Globals._hInstance, 0)) 00874 { 00875 } 00876 00877 00878 static RECT s_MyDrawText_Rect = {0, 0, 0, 0}; 00879 00880 static BOOL CALLBACK MyDrawText(HDC hdc, LPARAM data, int cnt) 00881 { 00882 ::DrawText(hdc, (LPCTSTR)data, cnt, &s_MyDrawText_Rect, DT_SINGLELINE); 00883 return TRUE; 00884 } 00885 00886 void DrawGrayText(HDC hdc, LPRECT pRect, LPCTSTR title, int dt_flags) 00887 { 00888 COLORREF gray = GetSysColor(COLOR_GRAYTEXT); 00889 00890 if (gray) { 00891 TextColor lcColor(hdc, GetSysColor(COLOR_BTNHIGHLIGHT)); 00892 RECT shadowRect = {pRect->left+1, pRect->top+1, pRect->right+1, pRect->bottom+1}; 00893 DrawText(hdc, title, -1, &shadowRect, dt_flags); 00894 00895 SetTextColor(hdc, gray); 00896 DrawText(hdc, title, -1, pRect, dt_flags); 00897 } else { 00898 int old_r = pRect->right; 00899 int old_b = pRect->bottom; 00900 00901 DrawText(hdc, title, -1, pRect, dt_flags|DT_CALCRECT); 00902 00903 int x = pRect->left + (old_r-pRect->right)/2; 00904 int y = pRect->top + (old_b-pRect->bottom)/2; 00905 int w = pRect->right-pRect->left; 00906 int h = pRect->bottom-pRect->top; 00907 s_MyDrawText_Rect.right = w; 00908 s_MyDrawText_Rect.bottom = h; 00909 00910 GrayString(hdc, GetSysColorBrush(COLOR_GRAYTEXT), MyDrawText, (LPARAM)title, -1, x, y, w, h); 00911 } 00912 } 00913 00914 00915 /* not yet used 00916 void ColorButton::DrawItem(LPDRAWITEMSTRUCT dis) 00917 { 00918 UINT state = DFCS_BUTTONPUSH; 00919 00920 if (dis->itemState & ODS_DISABLED) 00921 state |= DFCS_INACTIVE; 00922 00923 RECT textRect = {dis->rcItem.left+2, dis->rcItem.top+2, dis->rcItem.right-4, dis->rcItem.bottom-4}; 00924 00925 if (dis->itemState & ODS_SELECTED) { 00926 state |= DFCS_PUSHED; 00927 ++textRect.left; ++textRect.top; 00928 ++textRect.right; ++textRect.bottom; 00929 } 00930 00931 DrawFrameControl(dis->hDC, &dis->rcItem, DFC_BUTTON, state); 00932 00933 TCHAR title[BUFFER_LEN]; 00934 GetWindowText(_hwnd, title, BUFFER_LEN); 00935 00936 BkMode bk_mode(dis->hDC, TRANSPARENT); 00937 00938 if (dis->itemState & (ODS_DISABLED|ODS_GRAYED)) 00939 DrawGrayText(dis, &textRect, title, DT_SINGLELINE|DT_VCENTER|DT_CENTER); 00940 else { 00941 TextColor lcColor(dis->hDC, _textColor); 00942 DrawText(dis->hDC, title, -1, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); 00943 } 00944 00945 if (dis->itemState & ODS_FOCUS) { 00946 RECT rect = { 00947 dis->rcItem.left+3, dis->rcItem.top+3, 00948 dis->rcItem.right-dis->rcItem.left-4, dis->rcItem.bottom-dis->rcItem.top-4 00949 }; 00950 if (dis->itemState & ODS_SELECTED) { 00951 ++rect.left; ++rect.top; 00952 ++rect.right; ++rect.bottom; 00953 } 00954 DrawFocusRect(dis->hDC, &rect); 00955 } 00956 } 00957 */ 00958 00959 00960 void PictureButton::DrawItem(LPDRAWITEMSTRUCT dis) 00961 { 00962 UINT state = DFCS_BUTTONPUSH; 00963 int style = GetWindowStyle(_hwnd); 00964 00965 if (dis->itemState & ODS_DISABLED) 00966 state |= DFCS_INACTIVE; 00967 00968 POINT imagePos; 00969 RECT textRect; 00970 int dt_flags; 00971 00972 if (style & BS_BOTTOM) { 00973 // align horizontal centered, vertical floating 00974 imagePos.x = (dis->rcItem.left + dis->rcItem.right - _cx) / 2; 00975 imagePos.y = dis->rcItem.top + 3; 00976 00977 textRect.left = dis->rcItem.left + 2; 00978 textRect.top = dis->rcItem.top + _cy + 4; 00979 textRect.right = dis->rcItem.right - 4; 00980 textRect.bottom = dis->rcItem.bottom - 4; 00981 00982 dt_flags = DT_SINGLELINE|DT_CENTER|DT_VCENTER; 00983 } else { 00984 // horizontal floating, vertical centered 00985 imagePos.x = dis->rcItem.left + 3; 00986 imagePos.y = (dis->rcItem.top + dis->rcItem.bottom - _cy)/2; 00987 00988 textRect.left = dis->rcItem.left + _cx + 4; 00989 textRect.top = dis->rcItem.top + 2; 00990 textRect.right = dis->rcItem.right - 4; 00991 textRect.bottom = dis->rcItem.bottom - 4; 00992 00993 dt_flags = DT_SINGLELINE|DT_VCENTER/*|DT_CENTER*/; 00994 } 00995 00996 if (dis->itemState & ODS_SELECTED) { 00997 state |= DFCS_PUSHED; 00998 ++imagePos.x; ++imagePos.y; 00999 ++textRect.left; ++textRect.top; 01000 ++textRect.right; ++textRect.bottom; 01001 } 01002 01003 if (_flat) { 01004 FillRect(dis->hDC, &dis->rcItem, _hBrush); 01005 01006 if (style & BS_FLAT) // Only with BS_FLAT set, there will be drawn a frame without highlight. 01007 DrawEdge(dis->hDC, &dis->rcItem, EDGE_RAISED, BF_RECT|BF_FLAT); 01008 } else 01009 DrawFrameControl(dis->hDC, &dis->rcItem, DFC_BUTTON, state); 01010 01011 if (_hIcon) 01012 DrawIconEx(dis->hDC, imagePos.x, imagePos.y, _hIcon, _cx, _cy, 0, _hBrush, DI_NORMAL); 01013 else { 01014 MemCanvas mem_dc; 01015 BitmapSelection sel(mem_dc, _hBmp); 01016 BitBlt(dis->hDC, imagePos.x, imagePos.y, _cx, _cy, mem_dc, 0, 0, SRCCOPY); 01017 } 01018 01019 TCHAR title[BUFFER_LEN]; 01020 GetWindowText(_hwnd, title, BUFFER_LEN); 01021 01022 BkMode bk_mode(dis->hDC, TRANSPARENT); 01023 01024 if (dis->itemState & (ODS_DISABLED|ODS_GRAYED)) 01025 DrawGrayText(dis->hDC, &textRect, title, dt_flags); 01026 else { 01027 TextColor lcColor(dis->hDC, GetSysColor(COLOR_BTNTEXT)); 01028 DrawText(dis->hDC, title, -1, &textRect, dt_flags); 01029 } 01030 01031 if (dis->itemState & ODS_FOCUS) { 01032 RECT rect = { 01033 dis->rcItem.left+3, dis->rcItem.top+3, 01034 dis->rcItem.right-dis->rcItem.left-4, dis->rcItem.bottom-dis->rcItem.top-4 01035 }; 01036 if (dis->itemState & ODS_SELECTED) { 01037 ++rect.left; ++rect.top; 01038 ++rect.right; ++rect.bottom; 01039 } 01040 DrawFocusRect(dis->hDC, &rect); 01041 } 01042 } 01043 01044 01045 void FlatButton::DrawItem(LPDRAWITEMSTRUCT dis) 01046 { 01047 UINT style = DFCS_BUTTONPUSH; 01048 01049 if (dis->itemState & ODS_DISABLED) 01050 style |= DFCS_INACTIVE; 01051 01052 RECT textRect = {dis->rcItem.left+2, dis->rcItem.top+2, dis->rcItem.right-4, dis->rcItem.bottom-4}; 01053 01054 if (dis->itemState & ODS_SELECTED) { 01055 style |= DFCS_PUSHED; 01056 ++textRect.left; ++textRect.top; 01057 ++textRect.right; ++textRect.bottom; 01058 } 01059 01060 FillRect(dis->hDC, &dis->rcItem, GetSysColorBrush(COLOR_BTNFACE)); 01061 01062 // highlight the button? 01063 if (_active) 01064 DrawEdge(dis->hDC, &dis->rcItem, EDGE_ETCHED, BF_RECT); 01065 else if (GetWindowStyle(_hwnd) & BS_FLAT) // Only with BS_FLAT there will be drawn a frame to show highlighting. 01066 DrawEdge(dis->hDC, &dis->rcItem, EDGE_RAISED, BF_RECT|BF_FLAT); 01067 01068 TCHAR txt[BUFFER_LEN]; 01069 int txt_len = GetWindowText(_hwnd, txt, BUFFER_LEN); 01070 01071 if (dis->itemState & (ODS_DISABLED|ODS_GRAYED)) { 01072 COLORREF gray = GetSysColor(COLOR_GRAYTEXT); 01073 01074 if (gray) { 01075 { 01076 TextColor lcColor(dis->hDC, GetSysColor(COLOR_BTNHIGHLIGHT)); 01077 RECT shadowRect = {textRect.left+1, textRect.top+1, textRect.right+1, textRect.bottom+1}; 01078 DrawText(dis->hDC, txt, txt_len, &shadowRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); 01079 } 01080 01081 BkMode mode(dis->hDC, TRANSPARENT); 01082 TextColor lcColor(dis->hDC, gray); 01083 DrawText(dis->hDC, txt, txt_len, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); 01084 } else { 01085 int old_r = textRect.right; 01086 int old_b = textRect.bottom; 01087 DrawText(dis->hDC, txt, txt_len, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER|DT_CALCRECT); 01088 int x = textRect.left + (old_r-textRect.right)/2; 01089 int y = textRect.top + (old_b-textRect.bottom)/2; 01090 int w = textRect.right-textRect.left; 01091 int h = textRect.bottom-textRect.top; 01092 s_MyDrawText_Rect.right = w; 01093 s_MyDrawText_Rect.bottom = h; 01094 GrayString(dis->hDC, GetSysColorBrush(COLOR_GRAYTEXT), MyDrawText, (LPARAM)txt, txt_len, x, y, w, h); 01095 } 01096 } else { 01097 TextColor lcColor(dis->hDC, _active? _activeColor: _textColor); 01098 DrawText(dis->hDC, txt, txt_len, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER); 01099 } 01100 01101 if (dis->itemState & ODS_FOCUS) { 01102 RECT rect = { 01103 dis->rcItem.left+3, dis->rcItem.top+3, 01104 dis->rcItem.right-dis->rcItem.left-4, dis->rcItem.bottom-dis->rcItem.top-4 01105 }; 01106 if (dis->itemState & ODS_SELECTED) { 01107 ++rect.left; ++rect.top; 01108 ++rect.right; ++rect.bottom; 01109 } 01110 DrawFocusRect(dis->hDC, &rect); 01111 } 01112 } 01113 01114 LRESULT FlatButton::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 01115 { 01116 switch(nmsg) { 01117 case WM_MOUSEMOVE: { 01118 bool active = false; 01119 01120 if (IsWindowEnabled(_hwnd)) { 01121 DWORD pid_foreground; 01122 HWND hwnd_foreground = GetForegroundWindow(); //@@ may be better look for WM_ACTIVATEAPP ? 01123 GetWindowThreadProcessId(hwnd_foreground, &pid_foreground); 01124 01125 if (GetCurrentProcessId() == pid_foreground) { 01126 POINT pt = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)}; 01127 ClientRect clntRect(_hwnd); 01128 01129 // highlight the button? 01130 if (pt.x>=clntRect.left && pt.x<clntRect.right && pt.y>=clntRect.top && pt.y<clntRect.bottom) 01131 active = true; 01132 } 01133 } 01134 01135 if (active != _active) { 01136 _active = active; 01137 01138 if (active) { 01139 TRACKMOUSEEVENT tme = {sizeof(tme), /*TME_HOVER|*/TME_LEAVE, _hwnd/*, HOVER_DEFAULT*/}; 01140 _TrackMouseEvent(&tme); 01141 } 01142 01143 InvalidateRect(_hwnd, NULL, TRUE); 01144 } 01145 01146 return 0;} 01147 01148 case WM_LBUTTONUP: { 01149 POINT pt = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)}; 01150 ClientRect clntRect(_hwnd); 01151 01152 // no more in the active rectangle? 01153 if (pt.x<clntRect.left || pt.x>=clntRect.right || pt.y<clntRect.top || pt.y>=clntRect.bottom) 01154 goto cancel_press; 01155 01156 goto def;} 01157 01158 case WM_CANCELMODE: 01159 cancel_press: { 01160 TRACKMOUSEEVENT tme = {sizeof(tme), /*TME_HOVER|*/TME_LEAVE|TME_CANCEL, _hwnd/*, HOVER_DEFAULT*/}; 01161 _TrackMouseEvent(&tme); 01162 _active = false; 01163 ReleaseCapture();} 01164 // fall through 01165 01166 case WM_MOUSELEAVE: 01167 if (_active) { 01168 _active = false; 01169 01170 InvalidateRect(_hwnd, NULL, TRUE); 01171 } 01172 01173 return 0; 01174 01175 default: def: 01176 return super::WndProc(nmsg, wparam, lparam); 01177 } 01178 } 01179 01180 01181 HyperlinkCtrl::HyperlinkCtrl(HWND hwnd, COLORREF colorLink, COLORREF colorVisited) 01182 : super(hwnd), 01183 _cmd(ResString(GetDlgCtrlID(hwnd))), 01184 _textColor(colorLink), 01185 _colorVisited(colorVisited), 01186 _hfont(0), 01187 _crsr_link(0) 01188 { 01189 init(); 01190 } 01191 01192 HyperlinkCtrl::HyperlinkCtrl(HWND owner, int id, COLORREF colorLink, COLORREF colorVisited) 01193 : super(GetDlgItem(owner, id)), 01194 _cmd(ResString(id)), 01195 _textColor(colorLink), 01196 _colorVisited(colorVisited), 01197 _hfont(0), 01198 _crsr_link(0) 01199 { 01200 init(); 01201 } 01202 01203 void HyperlinkCtrl::init() 01204 { 01205 if (_cmd.empty()) { 01206 TCHAR txt[BUFFER_LEN]; 01207 _cmd.assign(txt, GetWindowText(_hwnd, txt, BUFFER_LEN)); 01208 } 01209 } 01210 01211 HyperlinkCtrl::~HyperlinkCtrl() 01212 { 01213 if (_hfont) 01214 DeleteObject(_hfont); 01215 } 01216 01217 LRESULT HyperlinkCtrl::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 01218 { 01219 switch(nmsg) { 01220 case PM_DISPATCH_CTLCOLOR: { 01221 if (!_hfont) { 01222 HFONT hfont = (HFONT) SendMessage(_hwnd, WM_GETFONT, 0, 0); 01223 LOGFONT lf; GetObject(hfont, sizeof(lf), &lf); 01224 lf.lfUnderline = TRUE; 01225 _hfont = CreateFontIndirect(&lf); 01226 } 01227 01228 HDC hdc = (HDC) wparam; 01229 SetTextColor(hdc, _textColor); //@@ 01230 SelectFont(hdc, _hfont); 01231 SetBkMode(hdc, TRANSPARENT); 01232 return (LRESULT)GetStockObject(HOLLOW_BRUSH); 01233 } 01234 01235 case WM_SETCURSOR: 01236 if (!_crsr_link) 01237 _crsr_link = LoadCursor(0, IDC_HAND); 01238 01239 if (_crsr_link) 01240 SetCursor(_crsr_link); 01241 return 0; 01242 01243 case WM_NCHITTEST: 01244 return HTCLIENT; // Aktivierung von Maus-Botschaften 01245 01246 case WM_LBUTTONDOWN: 01247 if (LaunchLink()) { 01248 _textColor = _colorVisited; 01249 InvalidateRect(_hwnd, NULL, FALSE); 01250 } else 01251 MessageBeep(0); 01252 return 0; 01253 01254 default: 01255 return super::WndProc(nmsg, wparam, lparam); 01256 } 01257 } 01258 01259 01260 ToolTip::ToolTip(HWND owner) 01261 : super(CreateWindowEx(WS_EX_TOPMOST|WS_EX_NOPARENTNOTIFY, TOOLTIPS_CLASS, 0, 01262 WS_POPUP|TTS_NOPREFIX|TTS_ALWAYSTIP, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, 01263 owner, 0, g_Globals._hInstance, 0)) 01264 { 01265 activate(); 01266 } 01267 01268 01269 ListSort::ListSort(HWND hwndListview, PFNLVCOMPARE compare_fct) 01270 : WindowHandle(hwndListview), 01271 _compare_fct(compare_fct) 01272 { 01273 _sort_crit = 0; 01274 _direction = false; 01275 } 01276 01277 void ListSort::toggle_sort(int idx) 01278 { 01279 if (_sort_crit == idx) 01280 _direction = !_direction; 01281 else { 01282 _sort_crit = idx; 01283 _direction = false; 01284 } 01285 } 01286 01287 void ListSort::sort() 01288 { 01289 int idx = ListView_GetSelectionMark(_hwnd); 01290 LPARAM param = ListView_GetItemData(_hwnd, idx); 01291 01292 ListView_SortItems(_hwnd, _compare_fct, (LPARAM)this); 01293 01294 if (idx >= 0) { 01295 idx = ListView_FindItemPara(_hwnd, param); 01296 ListView_EnsureVisible(_hwnd, idx, FALSE); 01297 } 01298 } 01299 01300 01301 PropSheetPage::PropSheetPage(UINT nid, Window::CREATORFUNC dlg_creator) 01302 : _dlg_creator(dlg_creator) 01303 { 01304 PROPSHEETPAGE::dwSize = sizeof(PROPSHEETPAGE); 01305 PROPSHEETPAGE::dwFlags = 0; 01306 PROPSHEETPAGE::hInstance = g_Globals._hInstance; 01307 PROPSHEETPAGE::pszTemplate = MAKEINTRESOURCE(nid); 01308 PROPSHEETPAGE::pfnDlgProc = PropSheetPageDlg::DialogProc; 01309 PROPSHEETPAGE::lParam = (LPARAM) this; 01310 } 01311 01312 01313 #ifndef PSM_GETRESULT // currently (as of 18.01.2004) missing in MinGW headers 01314 #define PSM_GETRESULT (WM_USER + 135) 01315 #define PropSheet_GetResult(hDlg) SNDMSG(hDlg, PSM_GETRESULT, 0, 0) 01316 #endif 01317 01318 01319 PropertySheetDialog::PropertySheetDialog(HWND owner) 01320 : _hwnd(0) 01321 { 01322 PROPSHEETHEADER::dwSize = sizeof(PROPSHEETHEADER); 01323 PROPSHEETHEADER::dwFlags = PSH_PROPSHEETPAGE | PSH_MODELESS; 01324 PROPSHEETHEADER::hwndParent = owner; 01325 PROPSHEETHEADER::hInstance = g_Globals._hInstance; 01326 } 01327 01328 void PropertySheetDialog::add(PropSheetPage& psp) 01329 { 01330 _pages.push_back(psp); 01331 } 01332 01333 int PropertySheetDialog::DoModal(int start_page) 01334 { 01335 PROPSHEETHEADER::ppsp = (LPCPROPSHEETPAGE) &_pages[0]; 01336 PROPSHEETHEADER::nPages = _pages.size(); 01337 PROPSHEETHEADER::nStartPage = start_page; 01338 /* 01339 Window* pwnd = Window::create_property_sheet(this, WINDOW_CREATOR(PropertySheetDlg), NULL); 01340 if (!pwnd) 01341 return -1; 01342 01343 HWND hwndPropSheet = *pwnd; 01344 */ 01345 int ret = PropertySheet(this); 01346 if (ret == -1) 01347 return -1; 01348 01349 HWND hwndPropSheet = (HWND) ret; 01350 HWND hwndparent = GetParent(hwndPropSheet); 01351 01352 if (hwndparent) 01353 EnableWindow(hwndparent, FALSE); 01354 01355 ret = 0; 01356 MSG msg; 01357 01358 while(GetMessage(&msg, 0, 0, 0)) { 01359 try { 01360 if (Window::pretranslate_msg(&msg)) 01361 continue; 01362 01363 if (PropSheet_IsDialogMessage(hwndPropSheet, &msg)) 01364 continue; 01365 01366 if (Window::dispatch_dialog_msg(&msg)) 01367 continue; 01368 01369 TranslateMessage(&msg); 01370 01371 try { 01372 DispatchMessage(&msg); 01373 } catch(COMException& e) { 01374 HandleException(e, 0); 01375 } 01376 01377 if (!PropSheet_GetCurrentPageHwnd(hwndPropSheet)) { 01378 ret = PropSheet_GetResult(hwndPropSheet); 01379 break; 01380 } 01381 } catch(COMException& e) { 01382 HandleException(e, 0); 01383 } 01384 } 01385 01386 if (hwndparent) 01387 EnableWindow(hwndparent, TRUE); 01388 01389 DestroyWindow(hwndPropSheet); 01390 01391 return ret; 01392 } 01393 01394 HWND PropertySheetDialog::GetCurrentPage() 01395 { 01396 HWND hdlg = PropSheet_GetCurrentPageHwnd(_hwnd); 01397 return hdlg; 01398 } 01399 01400 01401 PropSheetPageDlg::PropSheetPageDlg(HWND hwnd) 01402 : super(hwnd) 01403 { 01404 } 01405 01406 INT_PTR CALLBACK PropSheetPageDlg::DialogProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) 01407 { 01408 PropSheetPageDlg* pThis = GET_WINDOW(PropSheetPageDlg, hwnd); 01409 01410 if (pThis) { 01411 switch(nmsg) { 01412 case WM_COMMAND: 01413 pThis->Command(LOWORD(wparam), HIWORD(wparam)); 01414 return TRUE; // message has been processed 01415 01416 case WM_NOTIFY: 01417 pThis->Notify(wparam, (NMHDR*)lparam); 01418 return TRUE; // message has been processed 01419 01420 case WM_NOTIFYFORMAT: 01421 SetWindowLong(hwnd, DWLP_MSGRESULT, NFR_CURRENT); // set return value NFR_CURRENT 01422 return TRUE; // message has been processed 01423 01424 case WM_NCDESTROY: 01425 delete pThis; 01426 return TRUE; // message has been processed 01427 01428 default: 01429 return pThis->WndProc(nmsg, wparam, lparam); 01430 } 01431 } else if (nmsg == WM_INITDIALOG) { 01432 PROPSHEETPAGE* psp = (PROPSHEETPAGE*) lparam; 01433 PropSheetPage* ppsp = (PropSheetPage*) psp->lParam; 01434 01435 if (ppsp->_dlg_creator) { 01436 pThis = static_cast<PropSheetPageDlg*>(ppsp->_dlg_creator(hwnd)); 01437 01438 if (pThis) 01439 return pThis->Init(NULL); 01440 } 01441 } 01442 01443 return FALSE; // message has not been processed 01444 } 01445 01446 int PropSheetPageDlg::Command(int id, int code) 01447 { 01448 // override call to EndDialog in Dialog::Command(); 01449 01450 return FALSE; 01451 }
ROS Explorer Source Code Documentation
generated on 02.01.2013 by ![]() |