window.cpp

Go to the documentation of this file.
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 doxygen

ROS Explorer Homepage