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

commctrl.c
Go to the documentation of this file.
00001 /*
00002  * Common controls functions
00003  *
00004  * Copyright 1997 Dimitrie O. Paun
00005  * Copyright 1998,2000 Eric Kohl
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  *
00021  * NOTES
00022  * 
00023  * This code was audited for completeness against the documented features
00024  * of Comctl32.dll version 6.0 on Oct. 21, 2002, by Christian Neumair.
00025  *
00026  * Unless otherwise noted, we believe this code to be complete, as per
00027  * the specification mentioned above.
00028  * If you discover missing features, or bugs, please note them below.
00029  *
00030  * TODO
00031  *   -- implement GetMUILanguage + InitMUILanguage
00032  *   -- finish NOTES for MenuHelp, GetEffectiveClientRect and GetStatusTextW
00033  *   -- FIXMEs + BUGS (search for them)
00034  *
00035  * Control Classes
00036  *   -- ICC_ANIMATE_CLASS
00037  *   -- ICC_BAR_CLASSES
00038  *   -- ICC_COOL_CLASSES
00039  *   -- ICC_DATE_CLASSES
00040  *   -- ICC_HOTKEY_CLASS
00041  *   -- ICC_INTERNET_CLASSES
00042  *   -- ICC_LINK_CLASS
00043  *   -- ICC_LISTVIEW_CLASSES
00044  *   -- ICC_NATIVEFNTCTL_CLASS
00045  *   -- ICC_PAGESCROLLER_CLASS
00046  *   -- ICC_PROGRESS_CLASS
00047  *   -- ICC_STANDARD_CLASSES (not yet implemented)
00048  *   -- ICC_TAB_CLASSES
00049  *   -- ICC_TREEVIEW_CLASSES
00050  *   -- ICC_UPDOWN_CLASS
00051  *   -- ICC_USEREX_CLASSES
00052  *   -- ICC_WIN95_CLASSES
00053  */
00054 
00055 #include <stdarg.h>
00056 #include <string.h>
00057 #include <stdlib.h>
00058 
00059 #include "windef.h"
00060 #include "winbase.h"
00061 #include "wingdi.h"
00062 #include "winuser.h"
00063 #include "winnls.h"
00064 #include "commctrl.h"
00065 #include "winerror.h"
00066 #include "winreg.h"
00067 #define NO_SHLWAPI_STREAM
00068 #include "shlwapi.h"
00069 #include "comctl32.h"
00070 #include "wine/debug.h"
00071 
00072 WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
00073 
00074 #define NAME       L"microsoft.windows.common-controls"
00075 #define VERSION    L"6.0.2600.2982"
00076 #define PUBLIC_KEY L"6595b64144ccf1df"
00077 
00078 #ifdef __i386__
00079 #define ARCH L"x86"
00080 #elif defined __x86_64__
00081 #define ARCH L"amd64"
00082 #else
00083 #define ARCH L"none"
00084 #endif
00085 
00086 static const WCHAR manifest_filename[] = ARCH L"_" NAME L"_" PUBLIC_KEY L"_" VERSION L"_none_deadbeef.manifest";
00087 
00088 static LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
00089 
00090 static LPWSTR COMCTL32_wSubclass = NULL;
00091 HMODULE COMCTL32_hModule = 0;
00092 static LANGID COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
00093 HBRUSH  COMCTL32_hPattern55AABrush = NULL;
00094 COMCTL32_SysColor  comctl32_color;
00095 
00096 static HBITMAP COMCTL32_hPattern55AABitmap = NULL;
00097 
00098 static const WORD wPattern55AA[] =
00099 {
00100     0x5555, 0xaaaa, 0x5555, 0xaaaa,
00101     0x5555, 0xaaaa, 0x5555, 0xaaaa
00102 };
00103 
00104 static const WCHAR strCC32SubclassInfo[] = {
00105     'C','C','3','2','S','u','b','c','l','a','s','s','I','n','f','o',0
00106 };
00107 
00108 static BOOL create_manifest(BOOL install)
00109 {
00110     WCHAR *pwszBuf;
00111     HRSRC hResInfo;
00112     HGLOBAL hResData;
00113     PVOID pManifest;
00114     DWORD cchBuf, cbManifest, cbWritten;
00115     HANDLE hFile;
00116     BOOL bRet = FALSE;
00117 
00118     hResInfo = FindResourceW(COMCTL32_hModule, L"WINE_MANIFEST", RT_MANIFEST);
00119     if (!hResInfo)
00120         return FALSE;
00121 
00122     cbManifest = SizeofResource(COMCTL32_hModule, hResInfo);
00123     if (!cbManifest)
00124         return FALSE;
00125 
00126     hResData = LoadResource(COMCTL32_hModule, hResInfo);
00127     if (!hResData)
00128         return FALSE;
00129 
00130     pManifest = LockResource(hResData);
00131     if (!pManifest)
00132         return FALSE;
00133 
00134     cchBuf = GetWindowsDirectoryW(NULL, 0) * sizeof(WCHAR) + sizeof(L"\\winsxs\\manifests\\") + sizeof(manifest_filename);
00135     pwszBuf = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, cchBuf * sizeof(WCHAR));
00136     if (!pwszBuf)
00137         return FALSE;
00138 
00139     GetWindowsDirectoryW(pwszBuf, cchBuf);
00140     lstrcatW(pwszBuf, L"\\winsxs");
00141     CreateDirectoryW(pwszBuf, NULL);
00142     lstrcatW(pwszBuf, L"\\manifests\\");
00143     CreateDirectoryW(pwszBuf, NULL);
00144     lstrcatW(pwszBuf, manifest_filename);
00145     if (install)
00146     {
00147         hFile = CreateFileW(pwszBuf, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
00148         if (hFile != INVALID_HANDLE_VALUE)
00149         {
00150             if (WriteFile(hFile, pManifest, cbManifest, &cbWritten, NULL) && cbWritten == cbManifest)
00151                 bRet = TRUE;
00152 
00153             CloseHandle(hFile);
00154 
00155             if (!bRet)
00156                 DeleteFileW(pwszBuf);
00157             else
00158                 TRACE("created %s\n", debugstr_w(pwszBuf));
00159         }
00160     }
00161     else
00162         bRet = DeleteFileW(pwszBuf);
00163 
00164     HeapFree(GetProcessHeap(), 0, pwszBuf);
00165 
00166     return bRet;
00167 }
00168 
00169 
00170 /***********************************************************************
00171  * DllMain [Internal]
00172  *
00173  * Initializes the internal 'COMCTL32.DLL'.
00174  *
00175  * PARAMS
00176  *     hinstDLL    [I] handle to the 'dlls' instance
00177  *     fdwReason   [I]
00178  *     lpvReserved [I] reserved, must be NULL
00179  *
00180  * RETURNS
00181  *     Success: TRUE
00182  *     Failure: FALSE
00183  */
00184 
00185 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
00186 {
00187     TRACE("%p,%x,%p\n", hinstDLL, fdwReason, lpvReserved);
00188 
00189     switch (fdwReason) {
00190     case DLL_PROCESS_ATTACH:
00191             DisableThreadLibraryCalls(hinstDLL);
00192 
00193             COMCTL32_hModule = hinstDLL;
00194 
00195             /* add global subclassing atom (used by 'tooltip' and 'updown') */
00196             COMCTL32_wSubclass = (LPWSTR)(DWORD_PTR)GlobalAddAtomW (strCC32SubclassInfo);
00197             TRACE("Subclassing atom added: %p\n", COMCTL32_wSubclass);
00198 
00199             /* create local pattern brush */
00200             COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);
00201             COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);
00202 
00203         /* Get all the colors at DLL load */
00204         COMCTL32_RefreshSysColors();
00205 
00206             /* like comctl32 5.82+ register all the common control classes */
00207             ANIMATE_Register ();
00208             COMBOEX_Register ();
00209             DATETIME_Register ();
00210             FLATSB_Register ();
00211             HEADER_Register ();
00212             HOTKEY_Register ();
00213             IPADDRESS_Register ();
00214             LISTVIEW_Register ();
00215             MONTHCAL_Register ();
00216             NATIVEFONT_Register ();
00217             PAGER_Register ();
00218             PROGRESS_Register ();
00219             REBAR_Register ();
00220             STATUS_Register ();
00221             SYSLINK_Register ();
00222             TAB_Register ();
00223             TOOLBAR_Register ();
00224             TOOLTIPS_Register ();
00225             TRACKBAR_Register ();
00226             TREEVIEW_Register ();
00227             UPDOWN_Register ();
00228 
00229             /* subclass user32 controls */
00230             THEMING_Initialize ();
00231             break;
00232 
00233     case DLL_PROCESS_DETACH:
00234             /* clean up subclassing */ 
00235             THEMING_Uninitialize();
00236 
00237             /* unregister all common control classes */
00238             ANIMATE_Unregister ();
00239             COMBOEX_Unregister ();
00240             DATETIME_Unregister ();
00241             FLATSB_Unregister ();
00242             HEADER_Unregister ();
00243             HOTKEY_Unregister ();
00244             IPADDRESS_Unregister ();
00245             LISTVIEW_Unregister ();
00246             MONTHCAL_Unregister ();
00247             NATIVEFONT_Unregister ();
00248             PAGER_Unregister ();
00249             PROGRESS_Unregister ();
00250             REBAR_Unregister ();
00251             STATUS_Unregister ();
00252             SYSLINK_Unregister ();
00253             TAB_Unregister ();
00254             TOOLBAR_Unregister ();
00255             TOOLTIPS_Unregister ();
00256             TRACKBAR_Unregister ();
00257             TREEVIEW_Unregister ();
00258             UPDOWN_Unregister ();
00259 
00260             /* delete local pattern brush */
00261             DeleteObject (COMCTL32_hPattern55AABrush);
00262             COMCTL32_hPattern55AABrush = NULL;
00263             DeleteObject (COMCTL32_hPattern55AABitmap);
00264             COMCTL32_hPattern55AABitmap = NULL;
00265 
00266             /* delete global subclassing atom */
00267             GlobalDeleteAtom (LOWORD(COMCTL32_wSubclass));
00268             TRACE("Subclassing atom deleted: %p\n", COMCTL32_wSubclass);
00269             COMCTL32_wSubclass = NULL;
00270             break;
00271     }
00272 
00273     return TRUE;
00274 }
00275 
00276 
00277 /***********************************************************************
00278  * MenuHelp [COMCTL32.2]
00279  *
00280  * Handles the setting of status bar help messages when the user
00281  * selects menu items.
00282  *
00283  * PARAMS
00284  *     uMsg       [I] message (WM_MENUSELECT) (see NOTES)
00285  *     wParam     [I] wParam of the message uMsg
00286  *     lParam     [I] lParam of the message uMsg
00287  *     hMainMenu  [I] handle to the application's main menu
00288  *     hInst      [I] handle to the module that contains string resources
00289  *     hwndStatus [I] handle to the status bar window
00290  *     lpwIDs     [I] pointer to an array of integers (see NOTES)
00291  *
00292  * RETURNS
00293  *     No return value
00294  *
00295  * NOTES
00296  *     The official documentation is incomplete!
00297  *     This is the correct documentation:
00298  *
00299  *     uMsg:
00300  *     MenuHelp() does NOT handle WM_COMMAND messages! It only handles
00301  *     WM_MENUSELECT messages.
00302  *
00303  *     lpwIDs:
00304  *     (will be written ...)
00305  */
00306 
00307 VOID WINAPI
00308 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
00309       HINSTANCE hInst, HWND hwndStatus, UINT* lpwIDs)
00310 {
00311     UINT uMenuID = 0;
00312 
00313     if (!IsWindow (hwndStatus))
00314     return;
00315 
00316     switch (uMsg) {
00317     case WM_MENUSELECT:
00318         TRACE("WM_MENUSELECT wParam=0x%lX lParam=0x%lX\n",
00319            wParam, lParam);
00320 
00321             if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
00322                 /* menu was closed */
00323         TRACE("menu was closed!\n");
00324                 SendMessageW (hwndStatus, SB_SIMPLE, FALSE, 0);
00325             }
00326         else {
00327         /* menu item was selected */
00328         if (HIWORD(wParam) & MF_POPUP)
00329             uMenuID = *(lpwIDs+1);
00330         else
00331             uMenuID = (UINT)LOWORD(wParam);
00332         TRACE("uMenuID = %u\n", uMenuID);
00333 
00334         if (uMenuID) {
00335             WCHAR szText[256];
00336 
00337             if (!LoadStringW (hInst, uMenuID, szText, sizeof(szText)/sizeof(szText[0])))
00338             szText[0] = '\0';
00339 
00340             SendMessageW (hwndStatus, SB_SETTEXTW,
00341                     255 | SBT_NOBORDERS, (LPARAM)szText);
00342             SendMessageW (hwndStatus, SB_SIMPLE, TRUE, 0);
00343         }
00344         }
00345         break;
00346 
00347         case WM_COMMAND :
00348         TRACE("WM_COMMAND wParam=0x%lX lParam=0x%lX\n",
00349            wParam, lParam);
00350         /* WM_COMMAND is not invalid since it is documented
00351          * in the windows api reference. So don't output
00352              * any FIXME for WM_COMMAND
00353              */
00354         WARN("We don't care about the WM_COMMAND\n");
00355         break;
00356 
00357     default:
00358         FIXME("Invalid Message 0x%x!\n", uMsg);
00359         break;
00360     }
00361 }
00362 
00363 
00364 /***********************************************************************
00365  * ShowHideMenuCtl [COMCTL32.3]
00366  *
00367  * Shows or hides controls and updates the corresponding menu item.
00368  *
00369  * PARAMS
00370  *     hwnd   [I] handle to the client window.
00371  *     uFlags [I] menu command id.
00372  *     lpInfo [I] pointer to an array of integers. (See NOTES.)
00373  *
00374  * RETURNS
00375  *     Success: TRUE
00376  *     Failure: FALSE
00377  *
00378  * NOTES
00379  *     The official documentation is incomplete!
00380  *     This is the correct documentation:
00381  *
00382  *     hwnd
00383  *     Handle to the window that contains the menu and controls.
00384  *
00385  *     uFlags
00386  *     Identifier of the menu item to receive or lose a check mark.
00387  *
00388  *     lpInfo
00389  *     The array of integers contains pairs of values. BOTH values of
00390  *     the first pair must be the handles to the application's main menu.
00391  *     Each subsequent pair consists of a menu id and control id.
00392  */
00393 
00394 BOOL WINAPI
00395 ShowHideMenuCtl (HWND hwnd, UINT_PTR uFlags, LPINT lpInfo)
00396 {
00397     LPINT lpMenuId;
00398 
00399     TRACE("%p, %lx, %p\n", hwnd, uFlags, lpInfo);
00400 
00401     if (lpInfo == NULL)
00402     return FALSE;
00403 
00404     if (!(lpInfo[0]) || !(lpInfo[1]))
00405     return FALSE;
00406 
00407     /* search for control */
00408     lpMenuId = &lpInfo[2];
00409     while (*lpMenuId != uFlags)
00410     lpMenuId += 2;
00411 
00412     if (GetMenuState ((HMENU)(DWORD_PTR)lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
00413     /* uncheck menu item */
00414     CheckMenuItem ((HMENU)(DWORD_PTR)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
00415 
00416     /* hide control */
00417     lpMenuId++;
00418     SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
00419             SWP_HIDEWINDOW);
00420     }
00421     else {
00422     /* check menu item */
00423     CheckMenuItem ((HMENU)(DWORD_PTR)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
00424 
00425     /* show control */
00426     lpMenuId++;
00427     SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
00428             SWP_SHOWWINDOW);
00429     }
00430 
00431     return TRUE;
00432 }
00433 
00434 
00435 /***********************************************************************
00436  * GetEffectiveClientRect [COMCTL32.4]
00437  *
00438  * Calculates the coordinates of a rectangle in the client area.
00439  *
00440  * PARAMS
00441  *     hwnd   [I] handle to the client window.
00442  *     lpRect [O] pointer to the rectangle of the client window
00443  *     lpInfo [I] pointer to an array of integers (see NOTES)
00444  *
00445  * RETURNS
00446  *     No return value.
00447  *
00448  * NOTES
00449  *     The official documentation is incomplete!
00450  *     This is the correct documentation:
00451  *
00452  *     lpInfo
00453  *     (will be written ...)
00454  */
00455 
00456 VOID WINAPI
00457 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, const INT *lpInfo)
00458 {
00459     RECT rcCtrl;
00460     const INT *lpRun;
00461     HWND hwndCtrl;
00462 
00463     TRACE("(%p %p %p)\n",
00464        hwnd, lpRect, lpInfo);
00465 
00466     GetClientRect (hwnd, lpRect);
00467     lpRun = lpInfo;
00468 
00469     do {
00470     lpRun += 2;
00471     if (*lpRun == 0)
00472         return;
00473     lpRun++;
00474     hwndCtrl = GetDlgItem (hwnd, *lpRun);
00475     if (GetWindowLongW (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
00476         TRACE("control id 0x%x\n", *lpRun);
00477         GetWindowRect (hwndCtrl, &rcCtrl);
00478         MapWindowPoints (NULL, hwnd, (LPPOINT)&rcCtrl, 2);
00479         SubtractRect (lpRect, lpRect, &rcCtrl);
00480     }
00481     lpRun++;
00482     } while (*lpRun);
00483 }
00484 
00485 
00486 /***********************************************************************
00487  * DrawStatusTextW [COMCTL32.@]
00488  *
00489  * Draws text with borders, like in a status bar.
00490  *
00491  * PARAMS
00492  *     hdc   [I] handle to the window's display context
00493  *     lprc  [I] pointer to a rectangle
00494  *     text  [I] pointer to the text
00495  *     style [I] drawing style
00496  *
00497  * RETURNS
00498  *     No return value.
00499  *
00500  * NOTES
00501  *     The style variable can have one of the following values:
00502  *     (will be written ...)
00503  */
00504 
00505 void WINAPI DrawStatusTextW (HDC hdc, LPCRECT lprc, LPCWSTR text, UINT style)
00506 {
00507     RECT r = *lprc;
00508     UINT border = BDR_SUNKENOUTER;
00509 
00510     if (style & SBT_POPOUT)
00511         border = BDR_RAISEDOUTER;
00512     else if (style & SBT_NOBORDERS)
00513         border = 0;
00514 
00515     DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST);
00516 
00517     /* now draw text */
00518     if (text) {
00519         int oldbkmode = SetBkMode (hdc, TRANSPARENT);
00520         UINT align = DT_LEFT;
00521         int strCnt = 0;
00522 
00523         if (style & SBT_RTLREADING)
00524             FIXME("Unsupported RTL style!\n");
00525         r.left += 3;
00526         do {
00527             if (*text == '\t') {
00528                 if (strCnt) {
00529                     DrawTextW (hdc, text - strCnt, strCnt, &r, align|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX);
00530                     strCnt = 0;
00531                 }
00532                 if (align==DT_RIGHT) {
00533                     break;
00534                 }
00535                 align = (align==DT_LEFT ? DT_CENTER : DT_RIGHT);
00536             } else {
00537                 strCnt++;
00538             }
00539         } while(*text++);
00540 
00541         if (strCnt) DrawTextW (hdc, text - strCnt, -1, &r, align|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX);
00542     SetBkMode(hdc, oldbkmode);
00543     }
00544 }
00545 
00546 
00547 /***********************************************************************
00548  * DrawStatusText  [COMCTL32.@]
00549  * DrawStatusTextA [COMCTL32.5]
00550  *
00551  * Draws text with borders, like in a status bar.
00552  *
00553  * PARAMS
00554  *     hdc   [I] handle to the window's display context
00555  *     lprc  [I] pointer to a rectangle
00556  *     text  [I] pointer to the text
00557  *     style [I] drawing style
00558  *
00559  * RETURNS
00560  *     No return value.
00561  */
00562 
00563 void WINAPI DrawStatusTextA (HDC hdc, LPCRECT lprc, LPCSTR text, UINT style)
00564 {
00565     INT len;
00566     LPWSTR textW = NULL;
00567 
00568     if ( text ) {
00569     if ( (len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 )) ) {
00570         if ( (textW = Alloc( len * sizeof(WCHAR) )) )
00571         MultiByteToWideChar( CP_ACP, 0, text, -1, textW, len );
00572     }
00573     }
00574     DrawStatusTextW( hdc, lprc, textW, style );
00575     Free( textW );
00576 }
00577 
00578 
00579 /***********************************************************************
00580  * CreateStatusWindow  [COMCTL32.@]
00581  * CreateStatusWindowA [COMCTL32.6]
00582  *
00583  * Creates a status bar
00584  *
00585  * PARAMS
00586  *     style  [I] window style
00587  *     text   [I] pointer to the window text
00588  *     parent [I] handle to the parent window
00589  *     wid    [I] control id of the status bar
00590  *
00591  * RETURNS
00592  *     Success: handle to the status window
00593  *     Failure: 0
00594  */
00595 
00596 HWND WINAPI
00597 CreateStatusWindowA (LONG style, LPCSTR text, HWND parent, UINT wid)
00598 {
00599     return CreateWindowA(STATUSCLASSNAMEA, text, style,
00600                CW_USEDEFAULT, CW_USEDEFAULT,
00601                CW_USEDEFAULT, CW_USEDEFAULT,
00602                parent, (HMENU)(DWORD_PTR)wid, 0, 0);
00603 }
00604 
00605 
00606 /***********************************************************************
00607  * CreateStatusWindowW [COMCTL32.@]
00608  *
00609  * Creates a status bar control
00610  *
00611  * PARAMS
00612  *     style  [I] window style
00613  *     text   [I] pointer to the window text
00614  *     parent [I] handle to the parent window
00615  *     wid    [I] control id of the status bar
00616  *
00617  * RETURNS
00618  *     Success: handle to the status window
00619  *     Failure: 0
00620  */
00621 
00622 HWND WINAPI
00623 CreateStatusWindowW (LONG style, LPCWSTR text, HWND parent, UINT wid)
00624 {
00625     return CreateWindowW(STATUSCLASSNAMEW, text, style,
00626                CW_USEDEFAULT, CW_USEDEFAULT,
00627                CW_USEDEFAULT, CW_USEDEFAULT,
00628                parent, (HMENU)(DWORD_PTR)wid, 0, 0);
00629 }
00630 
00631 
00632 /***********************************************************************
00633  * CreateUpDownControl [COMCTL32.16]
00634  *
00635  * Creates an up-down control
00636  *
00637  * PARAMS
00638  *     style  [I] window styles
00639  *     x      [I] horizontal position of the control
00640  *     y      [I] vertical position of the control
00641  *     cx     [I] with of the control
00642  *     cy     [I] height of the control
00643  *     parent [I] handle to the parent window
00644  *     id     [I] the control's identifier
00645  *     inst   [I] handle to the application's module instance
00646  *     buddy  [I] handle to the buddy window, can be NULL
00647  *     maxVal [I] upper limit of the control
00648  *     minVal [I] lower limit of the control
00649  *     curVal [I] current value of the control
00650  *
00651  * RETURNS
00652  *     Success: handle to the updown control
00653  *     Failure: 0
00654  */
00655 
00656 HWND WINAPI
00657 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
00658              HWND parent, INT id, HINSTANCE inst,
00659              HWND buddy, INT maxVal, INT minVal, INT curVal)
00660 {
00661     HWND hUD =
00662     CreateWindowW (UPDOWN_CLASSW, 0, style, x, y, cx, cy,
00663              parent, (HMENU)(DWORD_PTR)id, inst, 0);
00664     if (hUD) {
00665     SendMessageW (hUD, UDM_SETBUDDY, (WPARAM)buddy, 0);
00666     SendMessageW (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
00667     SendMessageW (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
00668     }
00669 
00670     return hUD;
00671 }
00672 
00673 
00674 /***********************************************************************
00675  * InitCommonControls [COMCTL32.17]
00676  *
00677  * Registers the common controls.
00678  *
00679  * PARAMS
00680  *     No parameters.
00681  *
00682  * RETURNS
00683  *     No return values.
00684  *
00685  * NOTES
00686  *     This function is just a dummy - all the controls are registered at
00687  *     the DLL initialization time. See InitCommonContolsEx for details.
00688  */
00689 
00690 VOID WINAPI
00691 InitCommonControls (void)
00692 {
00693 }
00694 
00695 
00696 /***********************************************************************
00697  * InitCommonControlsEx [COMCTL32.@]
00698  *
00699  * Registers the common controls.
00700  *
00701  * PARAMS
00702  *     lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
00703  *
00704  * RETURNS
00705  *     Success: TRUE
00706  *     Failure: FALSE
00707  *
00708  * NOTES
00709  *     Probably all versions of comctl32 initializes the Win95 controls in DllMain
00710  *     during DLL initialization. Starting from comctl32 v5.82 all the controls
00711  *     are initialized there. We follow this behaviour and this function is just
00712  *     a dummy.
00713  *
00714  *     Note: when writing programs under Windows, if you don't call any function
00715  *     from comctl32 the linker may not link this DLL. If InitCommonControlsEx
00716  *     was the only comctl32 function you were calling and you remove it you may
00717  *     have a false impression that InitCommonControlsEx actually did something.
00718  */
00719 
00720 BOOL WINAPI
00721 InitCommonControlsEx (const INITCOMMONCONTROLSEX *lpInitCtrls)
00722 {
00723     if (!lpInitCtrls || lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
00724         return FALSE;
00725 
00726     TRACE("(0x%08x)\n", lpInitCtrls->dwICC);
00727     return TRUE;
00728 }
00729 
00730 
00731 /***********************************************************************
00732  * CreateToolbarEx [COMCTL32.@]
00733  *
00734  * Creates a toolbar window.
00735  *
00736  * PARAMS
00737  *     hwnd
00738  *     style
00739  *     wID
00740  *     nBitmaps
00741  *     hBMInst
00742  *     wBMID
00743  *     lpButtons
00744  *     iNumButtons
00745  *     dxButton
00746  *     dyButton
00747  *     dxBitmap
00748  *     dyBitmap
00749  *     uStructSize
00750  *
00751  * RETURNS
00752  *     Success: handle to the tool bar control
00753  *     Failure: 0
00754  */
00755 
00756 HWND WINAPI
00757 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
00758                  HINSTANCE hBMInst, UINT_PTR wBMID, LPCTBBUTTON lpButtons,
00759                  INT iNumButtons, INT dxButton, INT dyButton,
00760                  INT dxBitmap, INT dyBitmap, UINT uStructSize)
00761 {
00762     HWND hwndTB;
00763 
00764     hwndTB =
00765         CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL, style|WS_CHILD, 0,0,100,30,
00766                         hwnd, (HMENU)(DWORD_PTR)wID, COMCTL32_hModule, NULL);
00767     if(hwndTB) {
00768     TBADDBITMAP tbab;
00769 
00770         SendMessageW (hwndTB, TB_BUTTONSTRUCTSIZE, uStructSize, 0);
00771 
00772        /* set bitmap and button size */
00773        /*If CreateToolbarEx receives 0, windows sets default values*/
00774        if (dxBitmap < 0)
00775            dxBitmap = 16;
00776        if (dyBitmap < 0)
00777            dyBitmap = 16;
00778        if (dxBitmap == 0 || dyBitmap == 0)
00779            dxBitmap = dyBitmap = 16;
00780        SendMessageW(hwndTB, TB_SETBITMAPSIZE, 0, MAKELPARAM(dxBitmap, dyBitmap));
00781 
00782        if (dxButton < 0)
00783            dxButton = dxBitmap;
00784        if (dyButton < 0)
00785            dyButton = dyBitmap;
00786        /* TB_SETBUTTONSIZE -> TB_SETBITMAPSIZE bug introduced for Windows compatibility */
00787        if (dxButton != 0 && dyButton != 0)
00788             SendMessageW(hwndTB, TB_SETBITMAPSIZE, 0, MAKELPARAM(dxButton, dyButton));
00789 
00790 
00791     /* add bitmaps */
00792     if (nBitmaps > 0 || hBMInst == HINST_COMMCTRL)
00793     {
00794         tbab.hInst = hBMInst;
00795         tbab.nID   = wBMID;
00796 
00797             SendMessageW (hwndTB, TB_ADDBITMAP, nBitmaps, (LPARAM)&tbab);
00798     }
00799     /* add buttons */
00800     if(iNumButtons > 0)
00801         SendMessageW (hwndTB, TB_ADDBUTTONSW, iNumButtons, (LPARAM)lpButtons);
00802     }
00803 
00804     return hwndTB;
00805 }
00806 
00807 
00808 /***********************************************************************
00809  * CreateMappedBitmap [COMCTL32.8]
00810  *
00811  * Loads a bitmap resource using a colour map.
00812  *
00813  * PARAMS
00814  *     hInstance  [I] Handle to the module containing the bitmap.
00815  *     idBitmap   [I] The bitmap resource ID.
00816  *     wFlags     [I] CMB_MASKED for using bitmap as a mask or 0 for normal.
00817  *     lpColorMap [I] Colour information needed for the bitmap or NULL (uses system colours).
00818  *     iNumMaps   [I] Number of COLORMAP's pointed to by lpColorMap.
00819  *
00820  * RETURNS
00821  *     Success: handle to the new bitmap
00822  *     Failure: 0
00823  */
00824 
00825 HBITMAP WINAPI
00826 CreateMappedBitmap (HINSTANCE hInstance, INT_PTR idBitmap, UINT wFlags,
00827             LPCOLORMAP lpColorMap, INT iNumMaps)
00828 {
00829     HGLOBAL hglb;
00830     HRSRC hRsrc;
00831     const BITMAPINFOHEADER *lpBitmap;
00832     LPBITMAPINFOHEADER lpBitmapInfo;
00833     UINT nSize, nColorTableSize, iColor;
00834     RGBQUAD *pColorTable;
00835     INT i, iMaps, nWidth, nHeight;
00836     HDC hdcScreen;
00837     HBITMAP hbm;
00838     LPCOLORMAP sysColorMap;
00839     COLORREF cRef;
00840     COLORMAP internalColorMap[4] =
00841     {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
00842 
00843     /* initialize pointer to colortable and default color table */
00844     if (lpColorMap) {
00845     iMaps = iNumMaps;
00846     sysColorMap = lpColorMap;
00847     }
00848     else {
00849     internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
00850     internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
00851     internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
00852     internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
00853     iMaps = 4;
00854     sysColorMap = internalColorMap;
00855     }
00856 
00857     hRsrc = FindResourceW (hInstance, (LPWSTR)idBitmap, (LPWSTR)RT_BITMAP);
00858     if (hRsrc == 0)
00859     return 0;
00860     hglb = LoadResource (hInstance, hRsrc);
00861     if (hglb == 0)
00862     return 0;
00863     lpBitmap = LockResource (hglb);
00864     if (lpBitmap == NULL)
00865     return 0;
00866 
00867     if (lpBitmap->biSize >= sizeof(BITMAPINFOHEADER) && lpBitmap->biClrUsed)
00868         nColorTableSize = lpBitmap->biClrUsed;
00869     else if (lpBitmap->biBitCount <= 8) 
00870         nColorTableSize = (1 << lpBitmap->biBitCount);
00871     else
00872         nColorTableSize = 0;
00873     nSize = lpBitmap->biSize;
00874     if (nSize == sizeof(BITMAPINFOHEADER) && lpBitmap->biCompression == BI_BITFIELDS)
00875         nSize += 3 * sizeof(DWORD);
00876     nSize += nColorTableSize * sizeof(RGBQUAD);
00877     lpBitmapInfo = GlobalAlloc (GMEM_FIXED, nSize);
00878     if (lpBitmapInfo == NULL)
00879     return 0;
00880     RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
00881 
00882     pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo) + lpBitmapInfo->biSize);
00883 
00884     for (iColor = 0; iColor < nColorTableSize; iColor++) {
00885     for (i = 0; i < iMaps; i++) {
00886             cRef = RGB(pColorTable[iColor].rgbRed,
00887                        pColorTable[iColor].rgbGreen,
00888                        pColorTable[iColor].rgbBlue);
00889         if ( cRef  == sysColorMap[i].from) {
00890 #if 0
00891         if (wFlags & CBS_MASKED) {
00892             if (sysColorMap[i].to != COLOR_BTNTEXT)
00893             pColorTable[iColor] = RGB(255, 255, 255);
00894         }
00895         else
00896 #endif
00897                     pColorTable[iColor].rgbBlue  = GetBValue(sysColorMap[i].to);
00898                     pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
00899                     pColorTable[iColor].rgbRed   = GetRValue(sysColorMap[i].to);
00900         break;
00901         }
00902     }
00903     }
00904     nWidth  = lpBitmapInfo->biWidth;
00905     nHeight = lpBitmapInfo->biHeight;
00906     hdcScreen = GetDC (NULL);
00907     hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
00908     if (hbm) {
00909     HDC hdcDst = CreateCompatibleDC (hdcScreen);
00910     HBITMAP hbmOld = SelectObject (hdcDst, hbm);
00911     const BYTE *lpBits = (const BYTE *)lpBitmap + nSize;
00912     StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
00913                  lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
00914                  SRCCOPY);
00915     SelectObject (hdcDst, hbmOld);
00916     DeleteDC (hdcDst);
00917     }
00918     ReleaseDC (NULL, hdcScreen);
00919     GlobalFree (lpBitmapInfo);
00920     FreeResource (hglb);
00921 
00922     return hbm;
00923 }
00924 
00925 
00926 /***********************************************************************
00927  * CreateToolbar [COMCTL32.7]
00928  *
00929  * Creates a toolbar control.
00930  *
00931  * PARAMS
00932  *     hwnd
00933  *     style
00934  *     wID
00935  *     nBitmaps
00936  *     hBMInst
00937  *     wBMID
00938  *     lpButtons
00939  *     iNumButtons
00940  *
00941  * RETURNS
00942  *     Success: handle to the tool bar control
00943  *     Failure: 0
00944  *
00945  * NOTES
00946  *     Do not use this functions anymore. Use CreateToolbarEx instead.
00947  */
00948 
00949 HWND WINAPI
00950 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
00951            HINSTANCE hBMInst, UINT wBMID,
00952            LPCTBBUTTON lpButtons,INT iNumButtons)
00953 {
00954     return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
00955                 hBMInst, wBMID, lpButtons,
00956                 iNumButtons, 0, 0, 0, 0, CCSIZEOF_STRUCT(TBBUTTON, dwData));
00957 }
00958 
00959 
00960 /***********************************************************************
00961  * DllGetVersion [COMCTL32.@]
00962  *
00963  * Retrieves version information of the 'COMCTL32.DLL'
00964  *
00965  * PARAMS
00966  *     pdvi [O] pointer to version information structure.
00967  *
00968  * RETURNS
00969  *     Success: S_OK
00970  *     Failure: E_INVALIDARG
00971  *
00972  * NOTES
00973  *     Returns version of a comctl32.dll from IE4.01 SP1.
00974  */
00975 
00976 HRESULT WINAPI DllGetVersion (DLLVERSIONINFO *pdvi)
00977 {
00978     if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
00979         WARN("wrong DLLVERSIONINFO size from app\n");
00980     return E_INVALIDARG;
00981     }
00982 
00983     pdvi->dwMajorVersion = COMCTL32_VERSION;
00984     pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;
00985     pdvi->dwBuildNumber = 2919;
00986     pdvi->dwPlatformID = 6304;
00987 
00988     TRACE("%u.%u.%u.%u\n",
00989        pdvi->dwMajorVersion, pdvi->dwMinorVersion,
00990        pdvi->dwBuildNumber, pdvi->dwPlatformID);
00991 
00992     return S_OK;
00993 }
00994 
00995 /***********************************************************************
00996  *      DllInstall (COMCTL32.@)
00997  *
00998  * Installs the ComCtl32 DLL.
00999  *
01000  * RETURNS
01001  *     Success: S_OK
01002  *     Failure: A HRESULT error
01003  */
01004 HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
01005 {
01006     TRACE("(%u, %s): stub\n", bInstall, debugstr_w(cmdline));
01007     if (!create_manifest(bInstall))
01008     {
01009         ERR("create_manifest failed!\n");
01010         return HRESULT_FROM_WIN32(GetLastError());
01011     }
01012         
01013     return S_OK;
01014 }
01015 
01016 /***********************************************************************
01017  * _TrackMouseEvent [COMCTL32.@]
01018  *
01019  * Requests notification of mouse events
01020  *
01021  * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
01022  * to the hwnd specified in the ptme structure.  After the event message
01023  * is posted to the hwnd, the entry in the queue is removed.
01024  *
01025  * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
01026  * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
01027  * immediately and the TME_LEAVE flag being ignored.
01028  *
01029  * PARAMS
01030  *     ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
01031  *
01032  * RETURNS
01033  *     Success: non-zero
01034  *     Failure: zero
01035  *
01036  * IMPLEMENTATION moved to USER32.TrackMouseEvent
01037  *
01038  */
01039 
01040 BOOL WINAPI
01041 _TrackMouseEvent (TRACKMOUSEEVENT *ptme)
01042 {
01043     return TrackMouseEvent (ptme);
01044 }
01045 
01046 /*************************************************************************
01047  * GetMUILanguage [COMCTL32.@]
01048  *
01049  * Returns the user interface language in use by the current process.
01050  *
01051  * RETURNS
01052  *      Language ID in use by the current process.
01053  */
01054 LANGID WINAPI GetMUILanguage (VOID)
01055 {
01056     return COMCTL32_uiLang;
01057 }
01058 
01059 
01060 /*************************************************************************
01061  * InitMUILanguage [COMCTL32.@]
01062  *
01063  * Sets the user interface language to be used by the current process.
01064  *
01065  * RETURNS
01066  *      Nothing.
01067  */
01068 VOID WINAPI InitMUILanguage (LANGID uiLang)
01069 {
01070    COMCTL32_uiLang = uiLang;
01071 }
01072 
01073 
01074 /***********************************************************************
01075  * SetWindowSubclass [COMCTL32.410]
01076  *
01077  * Starts a window subclass
01078  *
01079  * PARAMS
01080  *     hWnd [in] handle to window subclass.
01081  *     pfnSubclass [in] Pointer to new window procedure.
01082  *     uIDSubclass [in] Unique identifier of subclass together with pfnSubclass.
01083  *     dwRef [in] Reference data to pass to window procedure.
01084  *
01085  * RETURNS
01086  *     Success: non-zero
01087  *     Failure: zero
01088  *
01089  * BUGS
01090  *     If an application manually subclasses a window after subclassing it with
01091  *     this API and then with this API again, then none of the previous 
01092  *     subclasses get called or the original window procedure.
01093  */
01094 
01095 BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
01096                         UINT_PTR uIDSubclass, DWORD_PTR dwRef)
01097 {
01098    LPSUBCLASS_INFO stack;
01099    LPSUBCLASSPROCS proc;
01100 
01101    TRACE ("(%p, %p, %lx, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);
01102 
01103    /* Since the window procedure that we set here has two additional arguments,
01104     * we can't simply set it as the new window procedure of the window. So we
01105     * set our own window procedure and then calculate the other two arguments
01106     * from there. */
01107 
01108    /* See if we have been called for this window */
01109    stack = GetPropW (hWnd, COMCTL32_wSubclass);
01110    if (!stack) {
01111       /* allocate stack */
01112       stack = Alloc (sizeof(SUBCLASS_INFO));
01113       if (!stack) {
01114          ERR ("Failed to allocate our Subclassing stack\n");
01115          return FALSE;
01116       }
01117       SetPropW (hWnd, COMCTL32_wSubclass, stack);
01118 
01119       /* set window procedure to our own and save the current one */
01120       if (IsWindowUnicode (hWnd))
01121          stack->origproc = (WNDPROC)SetWindowLongPtrW (hWnd, GWLP_WNDPROC,
01122                                                    (DWORD_PTR)COMCTL32_SubclassProc);
01123       else
01124          stack->origproc = (WNDPROC)SetWindowLongPtrA (hWnd, GWLP_WNDPROC,
01125                                                    (DWORD_PTR)COMCTL32_SubclassProc);
01126    }
01127    else {
01128       /* Check to see if we have called this function with the same uIDSubClass
01129        * and pfnSubclass */
01130       proc = stack->SubclassProcs;
01131       while (proc) {
01132          if ((proc->id == uIDSubclass) &&
01133             (proc->subproc == pfnSubclass)) {
01134             proc->ref = dwRef;
01135             return TRUE;
01136          }
01137          proc = proc->next;
01138       }
01139    }
01140    
01141    proc = Alloc(sizeof(SUBCLASSPROCS));
01142    if (!proc) {
01143       ERR ("Failed to allocate subclass entry in stack\n");
01144       if (IsWindowUnicode (hWnd))
01145          SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
01146       else
01147          SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
01148       Free (stack);
01149       RemovePropW( hWnd, COMCTL32_wSubclass );
01150       return FALSE;
01151    }
01152    
01153    proc->subproc = pfnSubclass;
01154    proc->ref = dwRef;
01155    proc->id = uIDSubclass;
01156    proc->next = stack->SubclassProcs;
01157    stack->SubclassProcs = proc;
01158 
01159    return TRUE;
01160 }
01161 
01162 
01163 /***********************************************************************
01164  * GetWindowSubclass [COMCTL32.411]
01165  *
01166  * Gets the Reference data from a subclass.
01167  *
01168  * PARAMS
01169  *     hWnd [in] Handle to window which were subclassing
01170  *     pfnSubclass [in] Pointer to the subclass procedure
01171  *     uID [in] Unique identifier of the subclassing procedure
01172  *     pdwRef [out] Pointer to the reference data
01173  *
01174  * RETURNS
01175  *     Success: Non-zero
01176  *     Failure: 0
01177  */
01178 
01179 BOOL WINAPI GetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
01180                               UINT_PTR uID, DWORD_PTR *pdwRef)
01181 {
01182    const SUBCLASS_INFO *stack;
01183    const SUBCLASSPROCS *proc;
01184 
01185    TRACE ("(%p, %p, %lx, %p)\n", hWnd, pfnSubclass, uID, pdwRef);
01186 
01187    /* See if we have been called for this window */
01188    stack = GetPropW (hWnd, COMCTL32_wSubclass);
01189    if (!stack)
01190       return FALSE;
01191 
01192    proc = stack->SubclassProcs;
01193    while (proc) {
01194       if ((proc->id == uID) &&
01195          (proc->subproc == pfnSubclass)) {
01196          *pdwRef = proc->ref;
01197          return TRUE;
01198       }
01199       proc = proc->next;
01200    }
01201 
01202    return FALSE;
01203 }
01204 
01205 
01206 /***********************************************************************
01207  * RemoveWindowSubclass [COMCTL32.412]
01208  *
01209  * Removes a window subclass.
01210  *
01211  * PARAMS
01212  *     hWnd [in] Handle to the window were subclassing
01213  *     pfnSubclass [in] Pointer to the subclass procedure
01214  *     uID [in] Unique identifier of this subclass
01215  *
01216  * RETURNS
01217  *     Success: non-zero
01218  *     Failure: zero
01219  */
01220 
01221 BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
01222 {
01223    LPSUBCLASS_INFO stack;
01224    LPSUBCLASSPROCS prevproc = NULL;
01225    LPSUBCLASSPROCS proc;
01226    BOOL ret = FALSE;
01227 
01228    TRACE ("(%p, %p, %lx)\n", hWnd, pfnSubclass, uID);
01229 
01230    /* Find the Subclass to remove */
01231    stack = GetPropW (hWnd, COMCTL32_wSubclass);
01232    if (!stack)
01233       return FALSE;
01234 
01235    proc = stack->SubclassProcs;
01236    while (proc) {
01237       if ((proc->id == uID) &&
01238          (proc->subproc == pfnSubclass)) {
01239          
01240          if (!prevproc)
01241             stack->SubclassProcs = proc->next;
01242          else
01243             prevproc->next = proc->next;
01244           
01245          if (stack->stackpos == proc)
01246             stack->stackpos = stack->stackpos->next;
01247             
01248          Free (proc);
01249          ret = TRUE;
01250          break;
01251       }
01252       prevproc = proc;
01253       proc = proc->next;
01254    }
01255    
01256    if (!stack->SubclassProcs && !stack->running) {
01257       TRACE("Last Subclass removed, cleaning up\n");
01258       /* clean up our heap and reset the original window procedure */
01259       if (IsWindowUnicode (hWnd))
01260          SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
01261       else
01262          SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
01263       Free (stack);
01264       RemovePropW( hWnd, COMCTL32_wSubclass );
01265    }
01266    
01267    return ret;
01268 }
01269 
01270 /***********************************************************************
01271  * COMCTL32_SubclassProc (internal)
01272  *
01273  * Window procedure for all subclassed windows. 
01274  * Saves the current subclassing stack position to support nested messages
01275  */
01276 static LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
01277 {
01278    LPSUBCLASS_INFO stack;
01279    LPSUBCLASSPROCS proc;
01280    LRESULT ret;
01281     
01282    TRACE ("(%p, 0x%08x, 0x%08lx, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);
01283 
01284    stack = GetPropW (hWnd, COMCTL32_wSubclass);
01285    if (!stack) {
01286       ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
01287       return 0;
01288    }
01289     
01290    /* Save our old stackpos to properly handle nested messages */
01291    proc = stack->stackpos;
01292    stack->stackpos = stack->SubclassProcs;
01293    stack->running++;
01294    ret = DefSubclassProc(hWnd, uMsg, wParam, lParam);
01295    stack->running--;
01296    stack->stackpos = proc;
01297     
01298    if (!stack->SubclassProcs && !stack->running) {
01299       TRACE("Last Subclass removed, cleaning up\n");
01300       /* clean up our heap and reset the original window procedure */
01301       if (IsWindowUnicode (hWnd))
01302          SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
01303       else
01304          SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
01305       Free (stack);
01306       RemovePropW( hWnd, COMCTL32_wSubclass );
01307    }
01308    return ret;
01309 }
01310 
01311 /***********************************************************************
01312  * DefSubclassProc [COMCTL32.413]
01313  *
01314  * Calls the next window procedure (i.e. the one before this subclass)
01315  *
01316  * PARAMS
01317  *     hWnd [in] The window that we're subclassing
01318  *     uMsg [in] Message
01319  *     wParam [in] WPARAM
01320  *     lParam [in] LPARAM
01321  *
01322  * RETURNS
01323  *     Success: non-zero
01324  *     Failure: zero
01325  */
01326 
01327 LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
01328 {
01329    LPSUBCLASS_INFO stack;
01330    LRESULT ret;
01331    
01332    TRACE ("(%p, 0x%08x, 0x%08lx, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);
01333 
01334    /* retrieve our little stack from the Properties */
01335    stack = GetPropW (hWnd, COMCTL32_wSubclass);
01336    if (!stack) {
01337       ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
01338       return 0;
01339    }
01340 
01341    /* If we are at the end of stack then we have to call the original
01342     * window procedure */
01343    if (!stack->stackpos) {
01344       if (IsWindowUnicode (hWnd))
01345          ret = CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam);
01346       else
01347          ret = CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);
01348    } else {
01349       const SUBCLASSPROCS *proc = stack->stackpos;
01350       stack->stackpos = stack->stackpos->next; 
01351       /* call the Subclass procedure from the stack */
01352       ret = proc->subproc (hWnd, uMsg, wParam, lParam,
01353             proc->id, proc->ref);
01354    }
01355 
01356    return ret;
01357 }
01358 
01359 
01360 /***********************************************************************
01361  * COMCTL32_CreateToolTip [NOT AN API]
01362  *
01363  * Creates a tooltip for the control specified in hwnd and does all
01364  * necessary setup and notifications.
01365  *
01366  * PARAMS
01367  *     hwndOwner [I] Handle to the window that will own the tool tip.
01368  *
01369  * RETURNS
01370  *     Success: Handle of tool tip window.
01371  *     Failure: NULL
01372  */
01373 
01374 HWND
01375 COMCTL32_CreateToolTip(HWND hwndOwner)
01376 {
01377     HWND hwndToolTip;
01378 
01379     hwndToolTip = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, WS_POPUP,
01380                   CW_USEDEFAULT, CW_USEDEFAULT,
01381                   CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,
01382                   0, 0, 0);
01383 
01384     /* Send NM_TOOLTIPSCREATED notification */
01385     if (hwndToolTip)
01386     {
01387     NMTOOLTIPSCREATED nmttc;
01388         /* true owner can be different if hwndOwner is a child window */
01389         HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);
01390         nmttc.hdr.hwndFrom = hwndTrueOwner;
01391         nmttc.hdr.idFrom = GetWindowLongPtrW(hwndTrueOwner, GWLP_ID);
01392     nmttc.hdr.code = NM_TOOLTIPSCREATED;
01393     nmttc.hwndToolTips = hwndToolTip;
01394 
01395         SendMessageW(GetParent(hwndTrueOwner), WM_NOTIFY,
01396                      GetWindowLongPtrW(hwndTrueOwner, GWLP_ID), (LPARAM)&nmttc);
01397     }
01398 
01399     return hwndToolTip;
01400 }
01401 
01402 
01403 /***********************************************************************
01404  * COMCTL32_RefreshSysColors [NOT AN API]
01405  *
01406  * Invoked on any control recognizing a WM_SYSCOLORCHANGE message to
01407  * refresh the color values in the color structure
01408  *
01409  * PARAMS
01410  *     none
01411  *
01412  * RETURNS
01413  *     none
01414  */
01415 
01416 VOID
01417 COMCTL32_RefreshSysColors(void)
01418 {
01419     comctl32_color.clrBtnHighlight = GetSysColor (COLOR_BTNHIGHLIGHT);
01420     comctl32_color.clrBtnShadow = GetSysColor (COLOR_BTNSHADOW);
01421     comctl32_color.clrBtnText = GetSysColor (COLOR_BTNTEXT);
01422     comctl32_color.clrBtnFace = GetSysColor (COLOR_BTNFACE);
01423     comctl32_color.clrHighlight = GetSysColor (COLOR_HIGHLIGHT);
01424     comctl32_color.clrHighlightText = GetSysColor (COLOR_HIGHLIGHTTEXT);
01425     comctl32_color.clrHotTrackingColor = GetSysColor (COLOR_HOTLIGHT);
01426     comctl32_color.clr3dHilight = GetSysColor (COLOR_3DHILIGHT);
01427     comctl32_color.clr3dShadow = GetSysColor (COLOR_3DSHADOW);
01428     comctl32_color.clr3dDkShadow = GetSysColor (COLOR_3DDKSHADOW);
01429     comctl32_color.clr3dFace = GetSysColor (COLOR_3DFACE);
01430     comctl32_color.clrWindow = GetSysColor (COLOR_WINDOW);
01431     comctl32_color.clrWindowText = GetSysColor (COLOR_WINDOWTEXT);
01432     comctl32_color.clrGrayText = GetSysColor (COLOR_GRAYTEXT);
01433     comctl32_color.clrActiveCaption = GetSysColor (COLOR_ACTIVECAPTION);
01434     comctl32_color.clrInfoBk = GetSysColor (COLOR_INFOBK);
01435     comctl32_color.clrInfoText = GetSysColor (COLOR_INFOTEXT);
01436 }
01437 
01438 /***********************************************************************
01439  * COMCTL32_DrawInsertMark [NOT AN API]
01440  *
01441  * Draws an insertion mark (which looks similar to an 'I').
01442  *
01443  * PARAMS
01444  *     hDC           [I] Device context to draw onto.
01445  *     lpRect        [I] Co-ordinates of insertion mark.
01446  *     clrInsertMark [I] Colour of the insertion mark.
01447  *     bHorizontal   [I] True if insert mark should be drawn horizontally,
01448  *                       vertical otherwise.
01449  *
01450  * RETURNS
01451  *     none
01452  *
01453  * NOTES
01454  *     Draws up to but not including the bottom co-ordinate when drawing
01455  *     vertically or the right co-ordinate when horizontal.
01456  */
01457 void COMCTL32_DrawInsertMark(HDC hDC, const RECT *lpRect, COLORREF clrInsertMark, BOOL bHorizontal)
01458 {
01459     HPEN hPen = CreatePen(PS_SOLID, 1, clrInsertMark);
01460     HPEN hOldPen;
01461     static const DWORD adwPolyPoints[] = {4,4,4};
01462     LONG lCentre = (bHorizontal ? 
01463         lpRect->top + (lpRect->bottom - lpRect->top)/2 : 
01464         lpRect->left + (lpRect->right - lpRect->left)/2);
01465     LONG l1 = (bHorizontal ? lpRect->left : lpRect->top);
01466     LONG l2 = (bHorizontal ? lpRect->right : lpRect->bottom);
01467     const POINT aptInsertMark[] =
01468     {
01469         /* top (V) or left (H) arrow */
01470         {lCentre    , l1 + 2},
01471         {lCentre - 2, l1    },
01472         {lCentre + 3, l1    },
01473         {lCentre + 1, l1 + 2},
01474         /* middle line */
01475         {lCentre    , l2 - 2},
01476         {lCentre    , l1 - 1},
01477         {lCentre + 1, l1 - 1},
01478         {lCentre + 1, l2 - 2},
01479         /* bottom (V) or right (H) arrow */
01480         {lCentre    , l2 - 3},
01481         {lCentre - 2, l2 - 1},
01482         {lCentre + 3, l2 - 1},
01483         {lCentre + 1, l2 - 3},
01484     };
01485     hOldPen = SelectObject(hDC, hPen);
01486     PolyPolyline(hDC, aptInsertMark, adwPolyPoints, sizeof(adwPolyPoints)/sizeof(adwPolyPoints[0]));
01487     SelectObject(hDC, hOldPen);
01488     DeleteObject(hPen);
01489 }
01490 
01491 /***********************************************************************
01492  * COMCTL32_EnsureBitmapSize [internal]
01493  *
01494  * If needed, enlarge the bitmap so that the width is at least cxMinWidth and
01495  * the height is at least cyMinHeight. If the bitmap already has these
01496  * dimensions nothing changes.
01497  *
01498  * PARAMS
01499  *     hBitmap       [I/O] Bitmap to modify. The handle may change
01500  *     cxMinWidth    [I]   If the width of the bitmap is smaller, then it will
01501  *                         be enlarged to this value
01502  *     cyMinHeight   [I]   If the height of the bitmap is smaller, then it will
01503  *                         be enlarged to this value
01504  *     cyBackground  [I]   The color with which the new area will be filled
01505  *
01506  * RETURNS
01507  *     none
01508  */
01509 void COMCTL32_EnsureBitmapSize(HBITMAP *pBitmap, int cxMinWidth, int cyMinHeight, COLORREF crBackground)
01510 {
01511     int cxNew, cyNew;
01512     BITMAP bmp;
01513     HBITMAP hNewBitmap;
01514     HBITMAP hNewDCBitmap, hOldDCBitmap;
01515     HBRUSH hNewDCBrush;
01516     HDC hdcNew, hdcOld;
01517 
01518     if (!GetObjectW(*pBitmap, sizeof(BITMAP), &bmp))
01519         return;
01520     cxNew = (cxMinWidth > bmp.bmWidth ? cxMinWidth : bmp.bmWidth);
01521     cyNew = (cyMinHeight > bmp.bmHeight ? cyMinHeight : bmp.bmHeight);
01522     if (cxNew == bmp.bmWidth && cyNew == bmp.bmHeight)
01523         return;
01524 
01525     hdcNew = CreateCompatibleDC(NULL);
01526     hNewBitmap = CreateBitmap(cxNew, cyNew, bmp.bmPlanes, bmp.bmBitsPixel, NULL);
01527     hNewDCBitmap = SelectObject(hdcNew, hNewBitmap);
01528     hNewDCBrush = SelectObject(hdcNew, CreateSolidBrush(crBackground));
01529 
01530     hdcOld = CreateCompatibleDC(NULL);
01531     hOldDCBitmap = SelectObject(hdcOld, *pBitmap);
01532 
01533     BitBlt(hdcNew, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcOld, 0, 0, SRCCOPY);
01534     if (bmp.bmWidth < cxMinWidth)
01535         PatBlt(hdcNew, bmp.bmWidth, 0, cxNew, bmp.bmHeight, PATCOPY);
01536     if (bmp.bmHeight < cyMinHeight)
01537         PatBlt(hdcNew, 0, bmp.bmHeight, bmp.bmWidth, cyNew, PATCOPY);
01538     if (bmp.bmWidth < cxMinWidth && bmp.bmHeight < cyMinHeight)
01539         PatBlt(hdcNew, bmp.bmWidth, bmp.bmHeight, cxNew, cyNew, PATCOPY);
01540 
01541     SelectObject(hdcNew, hNewDCBitmap);
01542     DeleteObject(SelectObject(hdcNew, hNewDCBrush));
01543     DeleteDC(hdcNew);
01544     SelectObject(hdcOld, hOldDCBitmap);
01545     DeleteDC(hdcOld);
01546 
01547     DeleteObject(*pBitmap);    
01548     *pBitmap = hNewBitmap;
01549     return;
01550 }
01551 
01552 void COMCTL32_GetFontMetrics(HFONT hFont, TEXTMETRICW *ptm)
01553 {
01554     HDC hdc = GetDC(NULL);
01555     HFONT hOldFont;
01556 
01557     hOldFont = SelectObject(hdc, hFont);
01558     GetTextMetricsW(hdc, ptm);
01559     SelectObject(hdc, hOldFont);
01560     ReleaseDC(NULL, hdc);
01561 }
01562 
01563 #ifndef OCM__BASE      /* avoid including olectl.h */
01564 #define OCM__BASE (WM_USER+0x1c00)
01565 #endif
01566 
01567 /***********************************************************************
01568  * COMCTL32_IsReflectedMessage [internal]
01569  *
01570  * Some parents reflect notify messages - for some messages sent by the child,
01571  * they send it back with the message code increased by OCM__BASE (0x2000).
01572  * This allows better subclassing of controls. We don't need to handle such
01573  * messages but we don't want to print ERRs for them, so this helper function
01574  * identifies them.
01575  *
01576  * Some of the codes are in the CCM_FIRST..CCM_LAST range, but there is no
01577  * colision with defined CCM_ codes.
01578  */
01579 BOOL COMCTL32_IsReflectedMessage(UINT uMsg)
01580 {
01581     switch (uMsg)
01582     {
01583         case OCM__BASE + WM_COMMAND:
01584         case OCM__BASE + WM_CTLCOLORBTN:
01585         case OCM__BASE + WM_CTLCOLOREDIT:
01586         case OCM__BASE + WM_CTLCOLORDLG:
01587         case OCM__BASE + WM_CTLCOLORLISTBOX:
01588         case OCM__BASE + WM_CTLCOLORMSGBOX:
01589         case OCM__BASE + WM_CTLCOLORSCROLLBAR:
01590         case OCM__BASE + WM_CTLCOLORSTATIC:
01591         case OCM__BASE + WM_DRAWITEM:
01592         case OCM__BASE + WM_MEASUREITEM:
01593         case OCM__BASE + WM_DELETEITEM:
01594         case OCM__BASE + WM_VKEYTOITEM:
01595         case OCM__BASE + WM_CHARTOITEM:
01596         case OCM__BASE + WM_COMPAREITEM:
01597         case OCM__BASE + WM_HSCROLL:
01598         case OCM__BASE + WM_VSCROLL:
01599         case OCM__BASE + WM_PARENTNOTIFY:
01600         case OCM__BASE + WM_NOTIFY:
01601             return TRUE;
01602         default:
01603             return FALSE;
01604     }
01605 }
01606 
01607 /***********************************************************************
01608  * MirrorIcon [COMCTL32.414]
01609  *
01610  * Mirrors an icon so that it will appear correctly on a mirrored DC.
01611  *
01612  * PARAMS
01613  *     phicon1 [I/O] Icon.
01614  *     phicon2 [I/O] Icon.
01615  *
01616  * RETURNS
01617  *     Success: TRUE.
01618  *     Failure: FALSE.
01619  */
01620 BOOL WINAPI MirrorIcon(HICON *phicon1, HICON *phicon2)
01621 {
01622     FIXME("(%p, %p): stub\n", phicon1, phicon2);
01623     return FALSE;
01624 }
01625 
01626 static inline int IsDelimiter(WCHAR c)
01627 {
01628     switch(c)
01629     {
01630     case '/':
01631     case '\\':
01632     case '.':
01633     case ' ':
01634         return TRUE;
01635     }
01636     return FALSE;
01637 }
01638 
01639 static int CALLBACK PathWordBreakProc(LPCWSTR lpch, int ichCurrent, int cch, int code)
01640 {
01641     if (code == WB_ISDELIMITER)
01642         return IsDelimiter(lpch[ichCurrent]);
01643     else
01644     {
01645         int dir = (code == WB_LEFT) ? -1 : 1;
01646         for(; 0 <= ichCurrent && ichCurrent < cch; ichCurrent += dir)
01647             if (IsDelimiter(lpch[ichCurrent])) return ichCurrent;
01648     }
01649     return ichCurrent;
01650 }
01651 
01652 /***********************************************************************
01653  * SetPathWordBreakProc [COMCTL32.384]
01654  *
01655  * Sets the word break procedure for an edit control to one that understands
01656  * paths so that the user can jump over directories.
01657  *
01658  * PARAMS
01659  *     hwnd [I] Handle to edit control.
01660  *     bSet [I] If this is TRUE then the word break proc is set, otherwise it is removed.
01661  *
01662  * RETURNS
01663  *     Result from EM_SETWORDBREAKPROC message.
01664  */
01665 LRESULT WINAPI SetPathWordBreakProc(HWND hwnd, BOOL bSet)
01666 {
01667     return SendMessageW(hwnd, EM_SETWORDBREAKPROC, 0,
01668         (LPARAM)(bSet ? PathWordBreakProc : NULL));
01669 }
01670 
01671 /***********************************************************************
01672  * DrawShadowText [COMCTL32.@]
01673  *
01674  * Draw text with shadow.
01675  */
01676 int WINAPI DrawShadowText(HDC hdc, LPCWSTR pszText, UINT cch, RECT *prc, DWORD dwFlags,
01677                           COLORREF crText, COLORREF crShadow, int ixOffset, int iyOffset)
01678 {
01679     COLORREF crOldText;
01680     RECT rcText;
01681     INT iRet, x, y, x2, y2;
01682     BYTE *pBits;
01683     HBITMAP hbm, hbmOld;
01684     BITMAPINFO bi;
01685     HDC hdcMem;
01686     HFONT hOldFont;
01687     BLENDFUNCTION bf;
01688 
01689     /* Create 32 bit DIB section for the shadow */
01690     ZeroMemory(&bi, sizeof(bi));
01691     bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
01692     bi.bmiHeader.biWidth = prc->right - prc->left + 4;
01693     bi.bmiHeader.biHeight = prc->bottom - prc->top + 5; // bottom-up DIB
01694     bi.bmiHeader.biPlanes = 1;
01695     bi.bmiHeader.biBitCount = 32;
01696     bi.bmiHeader.biCompression = BI_RGB;
01697     hbm = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (PVOID*)&pBits, NULL, 0);
01698     if(!hbm)
01699     {
01700         ERR("CreateDIBSection failed\n");
01701         return 0;
01702     }
01703 
01704     /* Create memory device context for new DIB section and select it */
01705     hdcMem = CreateCompatibleDC(hdc);
01706     if(!hdcMem)
01707     {
01708         ERR("CreateCompatibleDC failed\n");
01709         DeleteObject(hbm);
01710         return 0;
01711     }
01712 
01713     hbmOld = (HBITMAP)SelectObject(hdcMem, hbm);
01714 
01715     /* Draw text on our helper bitmap */
01716     hOldFont = (HFONT)SelectObject(hdcMem, GetCurrentObject(hdc, OBJ_FONT));
01717     SetTextColor(hdcMem, RGB(16, 16, 16));
01718     SetBkColor(hdcMem, RGB(0, 0, 0));
01719     SetBkMode(hdcMem, TRANSPARENT);
01720     SetRect(&rcText, 0, 0, prc->right - prc->left, prc->bottom - prc->top);
01721     DrawTextW(hdcMem, pszText, cch, &rcText, dwFlags);
01722     SelectObject(hdcMem, hOldFont);
01723 
01724     /* Flush GDI so data pointed by pBits is valid */
01725     GdiFlush();
01726 
01727     /* Set alpha of pixels (forget about colors for now. They will be changed in next loop).
01728        We copy text image 4*5 times and each time alpha is added */
01729     for (x = 0; x < bi.bmiHeader.biWidth; ++x)
01730         for (y = 0; y < bi.bmiHeader.biHeight; ++y)
01731         {
01732             BYTE *pDest = &pBits[(y * bi.bmiHeader.biWidth + x) * 4];
01733             UINT Alpha = 0;
01734 
01735             for (x2 = x - 4 + 1; x2 <= x; ++x2)
01736                 for (y2 = y; y2 < y + 5; ++y2)
01737                 {
01738                     if (x2 >= 0 && x2 < bi.bmiHeader.biWidth && y2 >= 0 && y2 < bi.bmiHeader.biHeight)
01739                     {
01740                         BYTE *pSrc = &pBits[(y2 * bi.bmiHeader.biWidth + x2) * 4];
01741                         Alpha += pSrc[0];
01742                     }
01743                 }
01744 
01745             if (Alpha > 255)
01746                 Alpha = 255;
01747             pDest[3] = Alpha;
01748         }
01749 
01750     /* Now set the color of each pixel to shadow color * alpha (see GdiAlphaBlend) */
01751     for (x = 0; x < bi.bmiHeader.biWidth; ++x)
01752         for (y = 0; y < bi.bmiHeader.biHeight; ++y)
01753         {
01754             BYTE *pDest = &pBits[(y * bi.bmiHeader.biWidth + x) * 4];
01755             pDest[0] = GetBValue(crShadow) * pDest[3] / 255;
01756             pDest[1] = GetGValue(crShadow) * pDest[3] / 255;
01757             pDest[2] = GetRValue(crShadow) * pDest[3] / 255;
01758         }
01759 
01760     /* Fix ixOffset of the shadow (tested on Win) */
01761     ixOffset -= 3;
01762     iyOffset -= 3;
01763 
01764     /* Alpha blend helper image to destination DC */
01765     bf.BlendOp = AC_SRC_OVER;
01766     bf.BlendFlags = 0;
01767     bf.SourceConstantAlpha = 255;
01768     bf.AlphaFormat = AC_SRC_ALPHA;
01769     if (!GdiAlphaBlend(hdc, prc->left + ixOffset, prc->top + iyOffset, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight, hdcMem, 0, 0, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight, bf))
01770         ERR("GdiAlphaBlend failed: %lu\n", GetLastError());
01771 
01772     /* Delete the helper bitmap */
01773     SelectObject(hdcMem, hbmOld);
01774     DeleteObject(hbm);
01775     DeleteDC(hdcMem);
01776 
01777     /* Finally draw the text over shadow */
01778     crOldText = SetTextColor(hdc, crText);
01779     SetBkMode(hdc, TRANSPARENT);
01780     iRet = DrawTextW(hdc, pszText, cch, prc, dwFlags);
01781     SetTextColor(hdc, crOldText);
01782 
01783     return iRet;
01784 }
01785 
01786 /***********************************************************************
01787  * TaskDialogIndirect [COMCTL32.@]
01788  */
01789 HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *pTaskConfig, int *pnButton,
01790                                   int *pnRadioButton, BOOL *pfVerificationFlagChecked)
01791 {
01792     UINT uType = 0;
01793     INT  ret;
01794     FIXME("%p, %p, %p, %p\n", pTaskConfig, pnButton, pnRadioButton, pfVerificationFlagChecked);
01795 
01796     if (pTaskConfig->dwCommonButtons & TDCBF_YES_BUTTON &&
01797         pTaskConfig->dwCommonButtons & TDCBF_NO_BUTTON &&
01798         pTaskConfig->dwCommonButtons & TDCBF_CANCEL_BUTTON)
01799         uType |= MB_YESNOCANCEL;
01800     else
01801     if (pTaskConfig->dwCommonButtons & TDCBF_YES_BUTTON &&
01802         pTaskConfig->dwCommonButtons & TDCBF_NO_BUTTON)
01803         uType |= MB_YESNO;
01804     else
01805     if (pTaskConfig->dwCommonButtons & TDCBF_RETRY_BUTTON &&
01806         pTaskConfig->dwCommonButtons & TDCBF_CANCEL_BUTTON)
01807         uType |= MB_RETRYCANCEL;
01808     else
01809     if (pTaskConfig->dwCommonButtons & TDCBF_OK_BUTTON &&
01810         pTaskConfig->dwCommonButtons & TDCBF_CANCEL_BUTTON)
01811         uType |= MB_OKCANCEL;
01812     else
01813     if (pTaskConfig->dwCommonButtons & TDCBF_OK_BUTTON)
01814         uType |= MB_OK;
01815     ret = MessageBoxW(pTaskConfig->hwndParent, pTaskConfig->pszMainInstruction,
01816                       pTaskConfig->pszWindowTitle, uType);
01817     FIXME("dwCommonButtons=%x uType=%x ret=%x\n", pTaskConfig->dwCommonButtons, uType, ret);
01818 
01819     if (pnButton) *pnButton = ret;
01820     if (pnRadioButton) *pnRadioButton = pTaskConfig->nDefaultButton;
01821     if (pfVerificationFlagChecked) *pfVerificationFlagChecked = TRUE;
01822     return S_OK;
01823 }
01824 
01825 /***********************************************************************
01826  * RegisterClassNameW [COMCTL32.@]
01827  *
01828  * Register window class again while using as SxS module.
01829  */
01830 BOOLEAN WINAPI RegisterClassNameW(LPCWSTR className)
01831 {
01832     /* FIXME: actually register redirected user32 class,
01833               comctl32 classes are registered by this module anyway */
01834     return TRUE;
01835 }

Generated on Sun May 27 2012 04:22:58 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.