ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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     this->hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
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 
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 
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:
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 
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 
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             SetWindowLongPtr(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             SetWindowLongPtr(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 }

Generated on Sat May 26 2012 04:17:38 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.