home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / Dita / source / w32control.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  10.2 KB  |  419 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Copyright (C) 1998-2004 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #include <stdafx.h>
  19. #include <vd2/system/w32assist.h>
  20. #include <vd2/Dita/w32control.h>
  21.  
  22. VDUIControlW32::~VDUIControlW32() {
  23.     Destroy();
  24. }
  25.  
  26. bool VDUIControlW32::CreateW32(IVDUIParameters *pParms, const char *pClass, DWORD flags) {
  27.     if (!VDUIPeerW32::Create(pParms))
  28.         return false;
  29.  
  30.     VDUIPeerW32 *pPeer = GetParentPeerW32();
  31.     HWND hwndParent = pPeer ? pPeer->GetHandleW32() : NULL;
  32.  
  33.     flags |= WS_VISIBLE;
  34.  
  35.     if (hwndParent)
  36.         flags |= WS_CHILD;
  37.  
  38.     DWORD exflags = 0;
  39.  
  40.     if (pParms->GetB(nsVDUI::kUIParam_Raised, !hwndParent))
  41.         exflags |= WS_EX_DLGMODALFRAME;
  42.  
  43.     if (pParms->GetB(nsVDUI::kUIParam_Sunken, false))
  44.         exflags |= WS_EX_CLIENTEDGE;
  45.  
  46.     const UINT id = mpBase->GetNextNativeID();
  47.  
  48.     if (VDIsWindowsNT())
  49.         mhwnd = CreateWindowExW(exflags, VDTextAToW(pClass).c_str(), mCaption.c_str(), flags, 0, 0, 0, 0, hwndParent, (HMENU)id, GetModuleHandle(NULL), NULL);
  50.     else
  51.         mhwnd = CreateWindowExA(exflags, pClass, VDTextWToA(mCaption).c_str(), flags, 0, 0, 0, 0, hwndParent, (HMENU)id, GetModuleHandle(NULL), NULL);
  52.  
  53.     if (!mhwnd)
  54.         return false;
  55.  
  56.     SendMessage(mhwnd, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE);
  57.  
  58.     if (pPeer)
  59.         pPeer->RegisterCallbackW32(this);
  60.  
  61.     if (pParms->GetB(nsVDUI::kUIParam_Default, false)) {
  62.         HWND hwndBase = vdpoly_cast<IVDUIWindowW32 *>(mpBase)->GetHandleW32();
  63.  
  64.         SendMessage(hwndBase, DM_SETDEFID, id, 0);
  65.         if (GetFocus() == hwndBase)
  66.             ::SetFocus(mhwnd);
  67.     }
  68.  
  69.     return true;
  70. }
  71.  
  72. void VDUIControlW32::Destroy() {
  73.     if (mhwnd) {
  74.         VDUIPeerW32 *pPeer = GetParentPeerW32();
  75.         if (pPeer)
  76.             pPeer->UnregisterCallbackW32(this);
  77.  
  78.         DestroyWindow(mhwnd);
  79.         mhwnd = NULL;
  80.     }
  81. }
  82.  
  83. void VDUIControlW32::PreLayoutBase(const VDUILayoutSpecs& specs) {
  84.     PreLayoutBaseW32(specs);
  85.  
  86.     RECT r = {0,0,mLayoutSpecs.minsize.w,mLayoutSpecs.minsize.h};
  87.  
  88.     DWORD dwStyle = GetWindowLong(mhwnd, GWL_STYLE);
  89.     bool bMenu = !(dwStyle & WS_CHILD) && GetMenu(mhwnd);
  90.  
  91.     AdjustWindowRectEx(&r, dwStyle, bMenu, GetWindowLong(mhwnd, GWL_EXSTYLE));
  92.  
  93.     mLayoutSpecs.minsize.w = r.right-r.left;
  94.     mLayoutSpecs.minsize.h = r.bottom-r.top;
  95. }
  96.  
  97. SIZE VDUIControlW32::SizeText(int nMaxWidth, int nPadWidth, int nPadHeight) {
  98.     SIZE siz = {0,0};
  99.  
  100.     if (nMaxWidth) {
  101.         nMaxWidth -= nPadWidth;
  102.  
  103.         // Uhh, negative is bad....
  104.  
  105.         if (nMaxWidth < 1)
  106.             nMaxWidth = 1;
  107.  
  108.     }
  109.  
  110.     const VDStringW caption(GetCaption());
  111.  
  112.     if (!VDIsWindowsNT()) {
  113.         VDStringA tempA(VDTextWToA(caption.c_str()));
  114.         const char *str = tempA.c_str();
  115.         HDC hdc;
  116.  
  117.         if (hdc = GetDC(mhwnd)) {
  118.             HGDIOBJ hgoOldFont;
  119.             RECT r={0,0,nMaxWidth};
  120.             DWORD dwFlags = DT_LEFT|DT_TOP|DT_CALCRECT;
  121.  
  122.             if (nMaxWidth)
  123.                 dwFlags |= DT_WORDBREAK;
  124.  
  125.             hgoOldFont = SelectObject(hdc, (HGDIOBJ)SendMessage(mhwnd, WM_GETFONT, 0, 0));
  126.  
  127.             if (DrawTextA(hdc, str, -1, &r, dwFlags)) {
  128.                 siz.cx = r.right - r.left;
  129.                 siz.cy = r.bottom - r.top;
  130.             }
  131.  
  132.             SelectObject(hdc, hgoOldFont);
  133.  
  134.             ReleaseDC(mhwnd, hdc);
  135.         }
  136.     } else {
  137.         HDC hdc;
  138.  
  139.         if (hdc = GetDC(mhwnd)) {
  140.             HGDIOBJ hgoOldFont;
  141.             RECT r={0,0,nMaxWidth};
  142.             DWORD dwFlags = DT_LEFT|DT_TOP|DT_CALCRECT;
  143.  
  144.             if (nMaxWidth)
  145.                 dwFlags |= DT_WORDBREAK;
  146.  
  147.             hgoOldFont = SelectObject(hdc, (HGDIOBJ)SendMessage(mhwnd, WM_GETFONT, 0, 0));
  148.  
  149.             if (DrawTextW(hdc, caption.c_str(), -1, &r, dwFlags)) {
  150.                 siz.cx = r.right - r.left;
  151.                 siz.cy = r.bottom - r.top;
  152.             }
  153.  
  154.             SelectObject(hdc, hgoOldFont);
  155.  
  156.             ReleaseDC(mhwnd, hdc);
  157.         }
  158.     }
  159.  
  160.     return siz;
  161. }
  162.  
  163. ///////////////////////////////////////////////////////////////////////////
  164.  
  165. namespace {
  166.     const struct VDDialogTemplateW32 {
  167.         WORD        dlgVer;
  168.         WORD        signature;
  169.         DWORD        helpID;
  170.         DWORD        exStyle;
  171.         DWORD        style;
  172.         WORD        cDlgItems;
  173.         short        x;
  174.         short        y;
  175.         short        cx;
  176.         short        cy;
  177.         short        menu;
  178.         WCHAR        windowClass[18];
  179.         WCHAR        title;
  180.         WORD        pointsize;
  181.         WORD        weight;
  182.         BYTE        italic;
  183.         BYTE        charset;
  184.         WCHAR        typeface[13];
  185.     } g_dummyDialogDef={
  186.         1,                    // dlgVer
  187.         0xFFFF,                // signature
  188.         0,                    // helpID
  189.         0,                    // exStyle
  190.         WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_CLIPSIBLINGS|DS_NOIDLEMSG|DS_SETFONT,
  191.         0,
  192.         0,
  193.         0,
  194.         0,
  195.         0,
  196.         0,                    // menu
  197.         L"DitaCustomControl",    // windowClass
  198.         0,                    // title
  199.         8,                    // pointsize
  200.         0,                    // weight
  201.         0,                    // italic
  202.         0,                    // charset
  203.         L"MS Shell Dlg"        // typeface
  204.     }, g_dummyDialogDefChild={
  205.         1,                    // dlgVer
  206.         0xFFFF,                // signature
  207.         0,                    // helpID
  208.         0,                    // exStyle
  209.         WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|DS_NOIDLEMSG|DS_SETFONT|DS_CONTROL,
  210.         0,
  211.         0,
  212.         0,
  213.         0,
  214.         0,
  215.         0,                    // menu
  216.         L"DitaCustomControl",    // windowClass
  217.         0,                    // title
  218.         8,                    // pointsize
  219.         0,                    // weight
  220.         0,                    // italic
  221.         0,                    // charset
  222.         L"MS Shell Dlg"        // typeface
  223.     };
  224. }
  225.  
  226. ATOM VDUICustomControlW32::sWindowClass = NULL;
  227.  
  228. bool VDUICustomControlW32::Create(IVDUIParameters *pParms, bool forceNonChild, DWORD flags) {
  229.     if (!VDUIPeerW32::Create(pParms))
  230.         return false;
  231.  
  232.     if (!sWindowClass) {
  233.         if (VDIsWindowsNT()) {
  234.             WNDCLASSW wc;
  235.  
  236.             wc.cbClsExtra        = 0;
  237.             wc.cbWndExtra        = DLGWINDOWEXTRA + sizeof(VDUICustomControlW32 *);
  238.             wc.hbrBackground    = (HBRUSH)(COLOR_3DFACE+1);
  239.             wc.hCursor            = LoadCursor(NULL, IDC_ARROW);
  240.             wc.hIcon            = 0;
  241.             wc.hInstance        = GetModuleHandle(NULL);
  242.             wc.lpfnWndProc        = StaticWndProc;
  243.             wc.lpszClassName    = L"DitaCustomControl";
  244.             wc.lpszMenuName        = NULL;
  245.             wc.style            = 0;
  246.  
  247.             sWindowClass = RegisterClassW(&wc);
  248.             if (!sWindowClass)
  249.                 return false;
  250.         } else {
  251.             WNDCLASSA wc;
  252.  
  253.             wc.cbClsExtra        = 0;
  254.             wc.cbWndExtra        = DLGWINDOWEXTRA + sizeof(VDUICustomControlW32 *);
  255.             wc.hbrBackground    = (HBRUSH)(COLOR_3DFACE+1);
  256.             wc.hCursor            = LoadCursor(NULL, IDC_ARROW);
  257.             wc.hIcon            = 0;
  258.             wc.hInstance        = GetModuleHandle(NULL);
  259.             wc.lpfnWndProc        = StaticWndProc;
  260.             wc.lpszClassName    = "DitaCustomControl";
  261.             wc.lpszMenuName        = NULL;
  262.             wc.style            = 0;
  263.  
  264.             sWindowClass = RegisterClassA(&wc);
  265.             if (!sWindowClass)
  266.                 return false;
  267.         }
  268.     }
  269.  
  270.     HWND hwndParent = GetParentW32();
  271.     DWORD exflags = 0;
  272.  
  273.     if (pParms->GetB(nsVDUI::kUIParam_Raised, !hwndParent))
  274.         exflags |= WS_EX_DLGMODALFRAME;
  275.  
  276.     if (pParms->GetB(nsVDUI::kUIParam_Sunken, false))
  277.         exflags |= WS_EX_CLIENTEDGE;
  278.  
  279.     VDDialogTemplateW32 templ;
  280.  
  281.     if (hwndParent && !forceNonChild)
  282.         templ = g_dummyDialogDefChild;
  283.     else
  284.         templ = g_dummyDialogDef;
  285.  
  286.     templ.style |= flags;
  287.     templ.exStyle = exflags;
  288.  
  289.     if (VDIsWindowsNT())
  290.         mhwnd = CreateDialogIndirectParamW(GetModuleHandle(NULL), (LPCDLGTEMPLATE)&templ, hwndParent, StaticDlgProc, (LPARAM)this);
  291.     else
  292.         mhwnd = CreateDialogIndirectParamA(GetModuleHandle(NULL), (LPCDLGTEMPLATE)&templ, hwndParent, StaticDlgProc, (LPARAM)this);
  293.  
  294.     if (mhwnd) {
  295.         VDSetWindowTextW32(mhwnd, mCaption.c_str());
  296.     }
  297.  
  298.     return !!mhwnd;
  299. }
  300.  
  301. void VDUICustomControlW32::Destroy() {
  302.     if (mhwnd)
  303.         DestroyWindow(mhwnd);
  304. }
  305.  
  306. INT_PTR CALLBACK VDUICustomControlW32::StaticDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
  307.     return FALSE;
  308. }
  309.  
  310. LRESULT CALLBACK VDUICustomControlW32::StaticWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
  311.     VDUICustomControlW32 *pThis;
  312.  
  313.     if (msg == WM_INITDIALOG) {
  314.         pThis = (VDUICustomControlW32 *)lParam;
  315.         pThis->mhwnd = hwnd;
  316.  
  317.         SetWindowLongPtr(hwnd, DLGWINDOWEXTRA, (LONG_PTR)pThis);
  318.     } else
  319.         pThis = (VDUICustomControlW32 *)GetWindowLongPtr(hwnd, DLGWINDOWEXTRA);
  320.  
  321.     return pThis ? pThis->WndProc(msg, wParam, lParam) : (VDIsWindowsNT() ? DefDlgProcW : DefDlgProcA)(hwnd, msg, wParam, lParam);
  322. }
  323.  
  324. namespace {
  325.     struct VDUIControlDialogW32ValidateData {
  326.         HWND hdlg;
  327.         HDC hdc;
  328.     };
  329.  
  330.     static BOOL CALLBACK ValidateEnumerator(HWND hwnd, LPARAM pData) {
  331.         VDUIControlDialogW32ValidateData& data = *(VDUIControlDialogW32ValidateData *)pData;
  332.         HBRUSH hbrBackground = (HBRUSH)GetClassLong(hwnd, GCLP_HBRBACKGROUND);
  333.  
  334.         if (hbrBackground) {
  335.             RECT r;
  336.  
  337.             GetWindowRect(hwnd, &r);
  338.             MapWindowPoints(NULL, data.hdlg, (LPPOINT)&r, 2);
  339.             ExcludeClipRect(data.hdc, r.left, r.top, r.right, r.bottom);
  340.         }
  341.  
  342.         return TRUE;
  343.     }
  344. }
  345.  
  346. LRESULT VDUICustomControlW32::WndProc(UINT msg, WPARAM wParam, LPARAM lParam) {
  347.     switch(msg) {
  348.     case WM_SIZE:
  349.         OnResize();
  350.  
  351.         if (!(GetWindowLong(mhwnd, GWL_STYLE) & WS_CHILD)) {
  352.             vduirect r(GetClientArea());
  353.  
  354.             tChildren::iterator it(mChildren.begin()), itEnd(mChildren.end());
  355.  
  356.             for(; it!=itEnd; ++it) {
  357.                 IVDUIWindow *pWin = *it;
  358.  
  359.                 pWin->PostLayout(r);
  360.             }
  361.         }
  362.         break;
  363.  
  364.     case WM_DESTROY:
  365.         mhwnd = NULL;
  366.         break;
  367.  
  368.     case WM_ERASEBKGND:
  369.         {
  370.             VDUIControlDialogW32ValidateData data = {mhwnd, (HDC)wParam};
  371.  
  372.             EnumChildWindows(mhwnd, ValidateEnumerator, (LPARAM)&data);
  373.         }
  374.         break;
  375.  
  376.     case WM_COMMAND:
  377.         {
  378.             tCallbacks::const_iterator it(mCallbacks.find((HWND)lParam));
  379.  
  380.             if (it != mCallbacks.end()) {
  381.                 VDUIPeerW32 *pPeer = (*it).second;
  382.  
  383.                 pPeer->OnCommandCallback(HIWORD(wParam));
  384.                 return 0;
  385.             }
  386.         }
  387.         break;
  388.  
  389.     case WM_NOTIFY:
  390.         {
  391.             const NMHDR& hdr = *(const NMHDR *)lParam;
  392.             tCallbacks::const_iterator it(mCallbacks.find(hdr.hwndFrom));
  393.  
  394.             if (it != mCallbacks.end()) {
  395.                 VDUIPeerW32 *pPeer = (*it).second;
  396.  
  397.                 pPeer->OnNotifyCallback(&hdr);
  398.                 return 0;
  399.             }
  400.         }
  401.  
  402.     case WM_HSCROLL:
  403.     case WM_VSCROLL:
  404.         {
  405.             tCallbacks::const_iterator it(mCallbacks.find((HWND)lParam));
  406.  
  407.             if (it != mCallbacks.end()) {
  408.                 VDUIPeerW32 *pPeer = (*it).second;
  409.  
  410.                 pPeer->OnScrollCallback(LOWORD(wParam));
  411.                 return 0;
  412.             }
  413.         }
  414.         break;
  415.     }
  416.  
  417.     return (VDIsWindowsNT() ? DefDlgProcW : DefDlgProcA)(mhwnd, msg, wParam, lParam);
  418. }
  419.