commctrl.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514
  1. /*
  2. * Common controls functions
  3. *
  4. * Copyright 1997 Dimitrie O. Paun
  5. * Copyright 1998,2000 Eric Kohl
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. *
  21. * NOTES
  22. *
  23. * This code was audited for completeness against the documented features
  24. * of Comctl32.dll version 6.0 on Oct. 21, 2002, by Christian Neumair.
  25. *
  26. * Unless otherwise noted, we believe this code to be complete, as per
  27. * the specification mentioned above.
  28. * If you discover missing features, or bugs, please note them below.
  29. *
  30. * TODO
  31. * -- implement GetMUILanguage + InitMUILanguage
  32. * -- LibMain => DLLMain ("DLLMain takes over the functionality of both the
  33. * LibMain and the WEP function.", MSDN)
  34. * -- finish NOTES for MenuHelp, GetEffectiveClientRect and GetStatusTextW
  35. * -- FIXMEs + BUGS (search for them)
  36. *
  37. * Control Classes
  38. * -- ICC_ANIMATE_CLASS
  39. * -- ICC_BAR_CLASSES
  40. * -- ICC_COOL_CLASSES
  41. * -- ICC_DATE_CLASSES
  42. * -- ICC_HOTKEY_CLASS
  43. * -- ICC_INTERNET_CLASSES
  44. * -- ICC_LINK_CLASS
  45. * -- ICC_LISTVIEW_CLASSES
  46. * -- ICC_NATIVEFNTCTL_CLASS
  47. * -- ICC_PAGESCROLLER_CLASS
  48. * -- ICC_PROGRESS_CLASS
  49. * -- ICC_STANDARD_CLASSES (not yet implemented)
  50. * -- ICC_TAB_CLASSES
  51. * -- ICC_TREEVIEW_CLASSES
  52. * -- ICC_UPDOWN_CLASS
  53. * -- ICC_USEREX_CLASSES
  54. * -- ICC_WIN95_CLASSES
  55. */
  56. #include <stdarg.h>
  57. #include <string.h>
  58. #include <stdlib.h>
  59. #include "windef.h"
  60. #include "winbase.h"
  61. #include "wingdi.h"
  62. #include "winuser.h"
  63. #include "winnls.h"
  64. #include "commctrl.h"
  65. #include "winerror.h"
  66. #include "winreg.h"
  67. #define NO_SHLWAPI_STREAM
  68. #include "shlwapi.h"
  69. #include "comctl32.h"
  70. #include "wine/debug.h"
  71. WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
  72. LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  73. LPWSTR COMCTL32_wSubclass = NULL;
  74. HMODULE COMCTL32_hModule = 0;
  75. LANGID COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
  76. HBRUSH COMCTL32_hPattern55AABrush = NULL;
  77. COMCTL32_SysColor comctl32_color;
  78. static HBITMAP COMCTL32_hPattern55AABitmap = NULL;
  79. static const WORD wPattern55AA[] =
  80. {
  81. 0x5555, 0xaaaa, 0x5555, 0xaaaa,
  82. 0x5555, 0xaaaa, 0x5555, 0xaaaa
  83. };
  84. static const WCHAR strCC32SubclassInfo[] = {
  85. 'C','C','3','2','S','u','b','c','l','a','s','s','I','n','f','o',0
  86. };
  87. /***********************************************************************
  88. * DllMain [Internal]
  89. *
  90. * Initializes the internal 'COMCTL32.DLL'.
  91. *
  92. * PARAMS
  93. * hinstDLL [I] handle to the 'dlls' instance
  94. * fdwReason [I]
  95. * lpvReserved [I] reserverd, must be NULL
  96. *
  97. * RETURNS
  98. * Success: TRUE
  99. * Failure: FALSE
  100. */
  101. BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
  102. {
  103. TRACE("%p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
  104. switch (fdwReason) {
  105. case DLL_PROCESS_ATTACH:
  106. DisableThreadLibraryCalls(hinstDLL);
  107. COMCTL32_hModule = (HMODULE)hinstDLL;
  108. /* add global subclassing atom (used by 'tooltip' and 'updown') */
  109. COMCTL32_wSubclass = (LPWSTR)(DWORD_PTR)GlobalAddAtomW (strCC32SubclassInfo);
  110. TRACE("Subclassing atom added: %p\n", COMCTL32_wSubclass);
  111. /* create local pattern brush */
  112. COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);
  113. COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);
  114. /* Get all the colors at DLL load */
  115. COMCTL32_RefreshSysColors();
  116. /* register all Win95 common control classes */
  117. ANIMATE_Register ();
  118. FLATSB_Register ();
  119. HEADER_Register ();
  120. HOTKEY_Register ();
  121. LISTVIEW_Register ();
  122. PROGRESS_Register ();
  123. STATUS_Register ();
  124. SYSLINK_Register ();
  125. TAB_Register ();
  126. TOOLBAR_Register ();
  127. TOOLTIPS_Register ();
  128. TRACKBAR_Register ();
  129. TREEVIEW_Register ();
  130. UPDOWN_Register ();
  131. /* subclass user32 controls */
  132. THEMING_Initialize ();
  133. break;
  134. case DLL_PROCESS_DETACH:
  135. /* clean up subclassing */
  136. THEMING_Uninitialize();
  137. /* unregister all common control classes */
  138. ANIMATE_Unregister ();
  139. COMBOEX_Unregister ();
  140. DATETIME_Unregister ();
  141. FLATSB_Unregister ();
  142. HEADER_Unregister ();
  143. HOTKEY_Unregister ();
  144. IPADDRESS_Unregister ();
  145. LISTVIEW_Unregister ();
  146. MONTHCAL_Unregister ();
  147. NATIVEFONT_Unregister ();
  148. PAGER_Unregister ();
  149. PROGRESS_Unregister ();
  150. REBAR_Unregister ();
  151. STATUS_Unregister ();
  152. SYSLINK_Unregister ();
  153. TAB_Unregister ();
  154. TOOLBAR_Unregister ();
  155. TOOLTIPS_Unregister ();
  156. TRACKBAR_Unregister ();
  157. TREEVIEW_Unregister ();
  158. UPDOWN_Unregister ();
  159. /* delete local pattern brush */
  160. DeleteObject (COMCTL32_hPattern55AABrush);
  161. COMCTL32_hPattern55AABrush = NULL;
  162. DeleteObject (COMCTL32_hPattern55AABitmap);
  163. COMCTL32_hPattern55AABitmap = NULL;
  164. /* delete global subclassing atom */
  165. GlobalDeleteAtom (LOWORD(COMCTL32_wSubclass));
  166. TRACE("Subclassing atom deleted: %p\n", COMCTL32_wSubclass);
  167. COMCTL32_wSubclass = NULL;
  168. break;
  169. }
  170. return TRUE;
  171. }
  172. /***********************************************************************
  173. * MenuHelp [COMCTL32.2]
  174. *
  175. * Handles the setting of status bar help messages when the user
  176. * selects menu items.
  177. *
  178. * PARAMS
  179. * uMsg [I] message (WM_MENUSELECT) (see NOTES)
  180. * wParam [I] wParam of the message uMsg
  181. * lParam [I] lParam of the message uMsg
  182. * hMainMenu [I] handle to the application's main menu
  183. * hInst [I] handle to the module that contains string resources
  184. * hwndStatus [I] handle to the status bar window
  185. * lpwIDs [I] pointer to an array of integers (see NOTES)
  186. *
  187. * RETURNS
  188. * No return value
  189. *
  190. * NOTES
  191. * The official documentation is incomplete!
  192. * This is the correct documentation:
  193. *
  194. * uMsg:
  195. * MenuHelp() does NOT handle WM_COMMAND messages! It only handles
  196. * WM_MENUSELECT messages.
  197. *
  198. * lpwIDs:
  199. * (will be written ...)
  200. */
  201. VOID WINAPI
  202. MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
  203. HINSTANCE hInst, HWND hwndStatus, UINT* lpwIDs)
  204. {
  205. UINT uMenuID = 0;
  206. if (!IsWindow (hwndStatus))
  207. return;
  208. switch (uMsg) {
  209. case WM_MENUSELECT:
  210. TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
  211. wParam, lParam);
  212. if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
  213. /* menu was closed */
  214. TRACE("menu was closed!\n");
  215. SendMessageW (hwndStatus, SB_SIMPLE, FALSE, 0);
  216. }
  217. else {
  218. /* menu item was selected */
  219. if (HIWORD(wParam) & MF_POPUP)
  220. uMenuID = (UINT)*(lpwIDs+1);
  221. else
  222. uMenuID = (UINT)LOWORD(wParam);
  223. TRACE("uMenuID = %u\n", uMenuID);
  224. if (uMenuID) {
  225. WCHAR szText[256];
  226. if (!LoadStringW (hInst, uMenuID, szText, sizeof(szText)/sizeof(szText[0])))
  227. szText[0] = '\0';
  228. SendMessageW (hwndStatus, SB_SETTEXTW,
  229. 255 | SBT_NOBORDERS, (LPARAM)szText);
  230. SendMessageW (hwndStatus, SB_SIMPLE, TRUE, 0);
  231. }
  232. }
  233. break;
  234. case WM_COMMAND :
  235. TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
  236. wParam, lParam);
  237. /* WM_COMMAND is not invalid since it is documented
  238. * in the windows api reference. So don't output
  239. * any FIXME for WM_COMMAND
  240. */
  241. WARN("We don't care about the WM_COMMAND\n");
  242. break;
  243. default:
  244. FIXME("Invalid Message 0x%x!\n", uMsg);
  245. break;
  246. }
  247. }
  248. /***********************************************************************
  249. * ShowHideMenuCtl [COMCTL32.3]
  250. *
  251. * Shows or hides controls and updates the corresponding menu item.
  252. *
  253. * PARAMS
  254. * hwnd [I] handle to the client window.
  255. * uFlags [I] menu command id.
  256. * lpInfo [I] pointer to an array of integers. (See NOTES.)
  257. *
  258. * RETURNS
  259. * Success: TRUE
  260. * Failure: FALSE
  261. *
  262. * NOTES
  263. * The official documentation is incomplete!
  264. * This is the correct documentation:
  265. *
  266. * hwnd
  267. * Handle to the window that contains the menu and controls.
  268. *
  269. * uFlags
  270. * Identifier of the menu item to receive or lose a check mark.
  271. *
  272. * lpInfo
  273. * The array of integers contains pairs of values. BOTH values of
  274. * the first pair must be the handles to the application's main menu.
  275. * Each subsequent pair consists of a menu id and control id.
  276. */
  277. BOOL WINAPI
  278. ShowHideMenuCtl (HWND hwnd, UINT_PTR uFlags, LPINT lpInfo)
  279. {
  280. LPINT lpMenuId;
  281. TRACE("%p, %x, %p\n", hwnd, uFlags, lpInfo);
  282. if (lpInfo == NULL)
  283. return FALSE;
  284. if (!(lpInfo[0]) || !(lpInfo[1]))
  285. return FALSE;
  286. /* search for control */
  287. lpMenuId = &lpInfo[2];
  288. while (*lpMenuId != uFlags)
  289. lpMenuId += 2;
  290. if (GetMenuState ((HMENU)(DWORD_PTR)lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
  291. /* uncheck menu item */
  292. CheckMenuItem ((HMENU)(DWORD_PTR)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
  293. /* hide control */
  294. lpMenuId++;
  295. SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
  296. SWP_HIDEWINDOW);
  297. }
  298. else {
  299. /* check menu item */
  300. CheckMenuItem ((HMENU)(DWORD_PTR)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
  301. /* show control */
  302. lpMenuId++;
  303. SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
  304. SWP_SHOWWINDOW);
  305. }
  306. return TRUE;
  307. }
  308. /***********************************************************************
  309. * GetEffectiveClientRect [COMCTL32.4]
  310. *
  311. * Calculates the coordinates of a rectangle in the client area.
  312. *
  313. * PARAMS
  314. * hwnd [I] handle to the client window.
  315. * lpRect [O] pointer to the rectangle of the client window
  316. * lpInfo [I] pointer to an array of integers (see NOTES)
  317. *
  318. * RETURNS
  319. * No return value.
  320. *
  321. * NOTES
  322. * The official documentation is incomplete!
  323. * This is the correct documentation:
  324. *
  325. * lpInfo
  326. * (will be written ...)
  327. */
  328. VOID WINAPI
  329. GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
  330. {
  331. RECT rcCtrl;
  332. INT *lpRun;
  333. HWND hwndCtrl;
  334. TRACE("(%p %p %p)\n",
  335. hwnd, lpRect, lpInfo);
  336. GetClientRect (hwnd, lpRect);
  337. lpRun = lpInfo;
  338. do {
  339. lpRun += 2;
  340. if (*lpRun == 0)
  341. return;
  342. lpRun++;
  343. hwndCtrl = GetDlgItem (hwnd, *lpRun);
  344. if (GetWindowLongW (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
  345. TRACE("control id 0x%x\n", *lpRun);
  346. GetWindowRect (hwndCtrl, &rcCtrl);
  347. MapWindowPoints (NULL, hwnd, (LPPOINT)&rcCtrl, 2);
  348. SubtractRect (lpRect, lpRect, &rcCtrl);
  349. }
  350. lpRun++;
  351. } while (*lpRun);
  352. }
  353. /***********************************************************************
  354. * DrawStatusTextW [COMCTL32.@]
  355. *
  356. * Draws text with borders, like in a status bar.
  357. *
  358. * PARAMS
  359. * hdc [I] handle to the window's display context
  360. * lprc [I] pointer to a rectangle
  361. * text [I] pointer to the text
  362. * style [I] drawing style
  363. *
  364. * RETURNS
  365. * No return value.
  366. *
  367. * NOTES
  368. * The style variable can have one of the following values:
  369. * (will be written ...)
  370. */
  371. void WINAPI DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)
  372. {
  373. RECT r = *lprc;
  374. UINT border = BDR_SUNKENOUTER;
  375. if (style & SBT_POPOUT)
  376. border = BDR_RAISEDOUTER;
  377. else if (style & SBT_NOBORDERS)
  378. border = 0;
  379. DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST);
  380. /* now draw text */
  381. if (text) {
  382. int oldbkmode = SetBkMode (hdc, TRANSPARENT);
  383. UINT align = DT_LEFT;
  384. if (*text == L'\t') {
  385. text++;
  386. align = DT_CENTER;
  387. if (*text == L'\t') {
  388. text++;
  389. align = DT_RIGHT;
  390. }
  391. }
  392. r.left += 3;
  393. if (style & SBT_RTLREADING)
  394. FIXME("Unsupported RTL style!\n");
  395. DrawTextW (hdc, text, -1, &r, align|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX);
  396. SetBkMode(hdc, oldbkmode);
  397. }
  398. }
  399. /***********************************************************************
  400. * DrawStatusText [COMCTL32.@]
  401. * DrawStatusTextA [COMCTL32.5]
  402. *
  403. * Draws text with borders, like in a status bar.
  404. *
  405. * PARAMS
  406. * hdc [I] handle to the window's display context
  407. * lprc [I] pointer to a rectangle
  408. * text [I] pointer to the text
  409. * style [I] drawing style
  410. *
  411. * RETURNS
  412. * No return value.
  413. */
  414. void WINAPI DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
  415. {
  416. INT len;
  417. LPWSTR textW = NULL;
  418. if ( text ) {
  419. if ( (len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 )) ) {
  420. if ( (textW = Alloc( len * sizeof(WCHAR) )) )
  421. MultiByteToWideChar( CP_ACP, 0, text, -1, textW, len );
  422. }
  423. }
  424. DrawStatusTextW( hdc, lprc, textW, style );
  425. Free( textW );
  426. }
  427. /***********************************************************************
  428. * CreateStatusWindow [COMCTL32.@]
  429. * CreateStatusWindowA [COMCTL32.6]
  430. *
  431. * Creates a status bar
  432. *
  433. * PARAMS
  434. * style [I] window style
  435. * text [I] pointer to the window text
  436. * parent [I] handle to the parent window
  437. * wid [I] control id of the status bar
  438. *
  439. * RETURNS
  440. * Success: handle to the status window
  441. * Failure: 0
  442. */
  443. HWND WINAPI
  444. CreateStatusWindowA (LONG style, LPCSTR text, HWND parent, UINT wid)
  445. {
  446. return CreateWindowA(STATUSCLASSNAMEA, text, style,
  447. CW_USEDEFAULT, CW_USEDEFAULT,
  448. CW_USEDEFAULT, CW_USEDEFAULT,
  449. parent, (HMENU)(DWORD_PTR)wid, 0, 0);
  450. }
  451. /***********************************************************************
  452. * CreateStatusWindowW [COMCTL32.@]
  453. *
  454. * Creates a status bar control
  455. *
  456. * PARAMS
  457. * style [I] window style
  458. * text [I] pointer to the window text
  459. * parent [I] handle to the parent window
  460. * wid [I] control id of the status bar
  461. *
  462. * RETURNS
  463. * Success: handle to the status window
  464. * Failure: 0
  465. */
  466. HWND WINAPI
  467. CreateStatusWindowW (LONG style, LPCWSTR text, HWND parent, UINT wid)
  468. {
  469. return CreateWindowW(STATUSCLASSNAMEW, text, style,
  470. CW_USEDEFAULT, CW_USEDEFAULT,
  471. CW_USEDEFAULT, CW_USEDEFAULT,
  472. parent, (HMENU)(DWORD_PTR)wid, 0, 0);
  473. }
  474. /***********************************************************************
  475. * CreateUpDownControl [COMCTL32.16]
  476. *
  477. * Creates an up-down control
  478. *
  479. * PARAMS
  480. * style [I] window styles
  481. * x [I] horizontal position of the control
  482. * y [I] vertical position of the control
  483. * cx [I] with of the control
  484. * cy [I] height of the control
  485. * parent [I] handle to the parent window
  486. * id [I] the control's identifier
  487. * inst [I] handle to the application's module instance
  488. * buddy [I] handle to the buddy window, can be NULL
  489. * maxVal [I] upper limit of the control
  490. * minVal [I] lower limit of the control
  491. * curVal [I] current value of the control
  492. *
  493. * RETURNS
  494. * Success: handle to the updown control
  495. * Failure: 0
  496. */
  497. HWND WINAPI
  498. CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
  499. HWND parent, INT id, HINSTANCE inst,
  500. HWND buddy, INT maxVal, INT minVal, INT curVal)
  501. {
  502. HWND hUD =
  503. CreateWindowW (UPDOWN_CLASSW, 0, style, x, y, cx, cy,
  504. parent, (HMENU)(DWORD_PTR)id, inst, 0);
  505. if (hUD) {
  506. SendMessageW (hUD, UDM_SETBUDDY, (WPARAM)buddy, 0);
  507. SendMessageW (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
  508. SendMessageW (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
  509. }
  510. return hUD;
  511. }
  512. /***********************************************************************
  513. * InitCommonControls [COMCTL32.17]
  514. *
  515. * Registers the common controls.
  516. *
  517. * PARAMS
  518. * No parameters.
  519. *
  520. * RETURNS
  521. * No return values.
  522. *
  523. * NOTES
  524. * This function is just a dummy.
  525. * The Win95 controls are registered at the DLL's initialization.
  526. * To register other controls InitCommonControlsEx() must be used.
  527. */
  528. VOID WINAPI
  529. InitCommonControls (void)
  530. {
  531. }
  532. /***********************************************************************
  533. * InitCommonControlsEx [COMCTL32.@]
  534. *
  535. * Registers the common controls.
  536. *
  537. * PARAMS
  538. * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
  539. *
  540. * RETURNS
  541. * Success: TRUE
  542. * Failure: FALSE
  543. *
  544. * NOTES
  545. * Only the additional common controls are registered by this function.
  546. * The Win95 controls are registered at the DLL's initialization.
  547. *
  548. * FIXME
  549. * implement the following control classes:
  550. * ICC_LINK_CLASS
  551. * ICC_STANDARD_CLASSES
  552. */
  553. BOOL WINAPI
  554. InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
  555. {
  556. INT cCount;
  557. DWORD dwMask;
  558. if (!lpInitCtrls)
  559. return FALSE;
  560. if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
  561. return FALSE;
  562. TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
  563. for (cCount = 0; cCount < 32; cCount++) {
  564. dwMask = 1 << cCount;
  565. if (!(lpInitCtrls->dwICC & dwMask))
  566. continue;
  567. switch (lpInitCtrls->dwICC & dwMask) {
  568. /* dummy initialization */
  569. case ICC_ANIMATE_CLASS:
  570. case ICC_BAR_CLASSES:
  571. case ICC_LISTVIEW_CLASSES:
  572. case ICC_TREEVIEW_CLASSES:
  573. case ICC_TAB_CLASSES:
  574. case ICC_UPDOWN_CLASS:
  575. case ICC_PROGRESS_CLASS:
  576. case ICC_HOTKEY_CLASS:
  577. break;
  578. /* advanced classes - not included in Win95 */
  579. case ICC_DATE_CLASSES:
  580. MONTHCAL_Register ();
  581. DATETIME_Register ();
  582. break;
  583. case ICC_USEREX_CLASSES:
  584. COMBOEX_Register ();
  585. break;
  586. case ICC_COOL_CLASSES:
  587. REBAR_Register ();
  588. break;
  589. case ICC_INTERNET_CLASSES:
  590. IPADDRESS_Register ();
  591. break;
  592. case ICC_PAGESCROLLER_CLASS:
  593. PAGER_Register ();
  594. break;
  595. case ICC_NATIVEFNTCTL_CLASS:
  596. NATIVEFONT_Register ();
  597. break;
  598. case ICC_LINK_CLASS:
  599. SYSLINK_Register ();
  600. break;
  601. default:
  602. FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
  603. break;
  604. }
  605. }
  606. return TRUE;
  607. }
  608. /***********************************************************************
  609. * CreateToolbarEx [COMCTL32.@]
  610. *
  611. * Creates a toolbar window.
  612. *
  613. * PARAMS
  614. * hwnd
  615. * style
  616. * wID
  617. * nBitmaps
  618. * hBMInst
  619. * wBMID
  620. * lpButtons
  621. * iNumButtons
  622. * dxButton
  623. * dyButton
  624. * dxBitmap
  625. * dyBitmap
  626. * uStructSize
  627. *
  628. * RETURNS
  629. * Success: handle to the tool bar control
  630. * Failure: 0
  631. */
  632. HWND WINAPI
  633. CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
  634. HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
  635. INT iNumButtons, INT dxButton, INT dyButton,
  636. INT dxBitmap, INT dyBitmap, UINT uStructSize)
  637. {
  638. HWND hwndTB;
  639. hwndTB =
  640. CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL, style|WS_CHILD, 0,0,100,30,
  641. hwnd, (HMENU)(DWORD_PTR)wID, COMCTL32_hModule, NULL);
  642. if(hwndTB) {
  643. TBADDBITMAP tbab;
  644. SendMessageW (hwndTB, TB_BUTTONSTRUCTSIZE, (WPARAM)uStructSize, 0);
  645. /* set bitmap and button size */
  646. /*If CreateToolbarEx receives 0, windows sets default values*/
  647. if (dxBitmap <= 0)
  648. dxBitmap = 16;
  649. if (dyBitmap <= 0)
  650. dyBitmap = 15;
  651. SendMessageW (hwndTB, TB_SETBITMAPSIZE, 0,
  652. MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap));
  653. if (dxButton <= 0)
  654. dxButton = 24;
  655. if (dyButton <= 0)
  656. dyButton = 22;
  657. SendMessageW (hwndTB, TB_SETBUTTONSIZE, 0,
  658. MAKELPARAM((WORD)dxButton, (WORD)dyButton));
  659. /* add bitmaps */
  660. if (nBitmaps > 0)
  661. {
  662. tbab.hInst = hBMInst;
  663. tbab.nID = wBMID;
  664. SendMessageW (hwndTB, TB_ADDBITMAP, (WPARAM)nBitmaps, (LPARAM)&tbab);
  665. }
  666. /* add buttons */
  667. if(iNumButtons > 0)
  668. SendMessageW (hwndTB, TB_ADDBUTTONSW,
  669. (WPARAM)iNumButtons, (LPARAM)lpButtons);
  670. }
  671. return hwndTB;
  672. }
  673. /***********************************************************************
  674. * CreateMappedBitmap [COMCTL32.8]
  675. *
  676. * Loads a bitmap resource using a colour map.
  677. *
  678. * PARAMS
  679. * hInstance [I] Handle to the module containing the bitmap.
  680. * idBitmap [I] The bitmap resource ID.
  681. * wFlags [I] CMB_MASKED for using bitmap as a mask or 0 for normal.
  682. * lpColorMap [I] Colour information needed for the bitmap or NULL (uses system colours).
  683. * iNumMaps [I] Number of COLORMAP's pointed to by lpColorMap.
  684. *
  685. * RETURNS
  686. * Success: handle to the new bitmap
  687. * Failure: 0
  688. */
  689. HBITMAP WINAPI
  690. CreateMappedBitmap (HINSTANCE hInstance, INT_PTR idBitmap, UINT wFlags,
  691. LPCOLORMAP lpColorMap, INT iNumMaps)
  692. {
  693. HGLOBAL hglb;
  694. HRSRC hRsrc;
  695. LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
  696. UINT nSize, nColorTableSize, iColor;
  697. RGBQUAD *pColorTable;
  698. INT i, iMaps, nWidth, nHeight;
  699. HDC hdcScreen;
  700. HBITMAP hbm;
  701. LPCOLORMAP sysColorMap;
  702. COLORREF cRef;
  703. COLORMAP internalColorMap[4] =
  704. {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
  705. /* initialize pointer to colortable and default color table */
  706. if (lpColorMap) {
  707. iMaps = iNumMaps;
  708. sysColorMap = lpColorMap;
  709. }
  710. else {
  711. internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
  712. internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
  713. internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
  714. internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
  715. iMaps = 4;
  716. sysColorMap = (LPCOLORMAP)internalColorMap;
  717. }
  718. hRsrc = FindResourceW (hInstance, (LPWSTR)idBitmap, (LPWSTR)RT_BITMAP);
  719. if (hRsrc == 0)
  720. return 0;
  721. hglb = LoadResource (hInstance, hRsrc);
  722. if (hglb == 0)
  723. return 0;
  724. lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
  725. if (lpBitmap == NULL)
  726. return 0;
  727. if (lpBitmap->biSize >= sizeof(BITMAPINFOHEADER) && lpBitmap->biClrUsed)
  728. nColorTableSize = lpBitmap->biClrUsed;
  729. else if (lpBitmap->biBitCount <= 8)
  730. nColorTableSize = (1 << lpBitmap->biBitCount);
  731. else
  732. nColorTableSize = 0;
  733. nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
  734. lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
  735. if (lpBitmapInfo == NULL)
  736. return 0;
  737. RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
  738. pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);
  739. for (iColor = 0; iColor < nColorTableSize; iColor++) {
  740. for (i = 0; i < iMaps; i++) {
  741. cRef = RGB(pColorTable[iColor].rgbRed,
  742. pColorTable[iColor].rgbGreen,
  743. pColorTable[iColor].rgbBlue);
  744. if ( cRef == sysColorMap[i].from) {
  745. #if 0
  746. if (wFlags & CBS_MASKED) {
  747. if (sysColorMap[i].to != COLOR_BTNTEXT)
  748. pColorTable[iColor] = RGB(255, 255, 255);
  749. }
  750. else
  751. #endif
  752. pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to);
  753. pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
  754. pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to);
  755. break;
  756. }
  757. }
  758. }
  759. nWidth = (INT)lpBitmapInfo->biWidth;
  760. nHeight = (INT)lpBitmapInfo->biHeight;
  761. hdcScreen = GetDC (NULL);
  762. hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
  763. if (hbm) {
  764. HDC hdcDst = CreateCompatibleDC (hdcScreen);
  765. HBITMAP hbmOld = SelectObject (hdcDst, hbm);
  766. LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
  767. lpBits += nColorTableSize * sizeof(RGBQUAD);
  768. StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
  769. lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
  770. SRCCOPY);
  771. SelectObject (hdcDst, hbmOld);
  772. DeleteDC (hdcDst);
  773. }
  774. ReleaseDC (NULL, hdcScreen);
  775. GlobalFree ((HGLOBAL)lpBitmapInfo);
  776. FreeResource (hglb);
  777. return hbm;
  778. }
  779. /***********************************************************************
  780. * CreateToolbar [COMCTL32.7]
  781. *
  782. * Creates a toolbar control.
  783. *
  784. * PARAMS
  785. * hwnd
  786. * style
  787. * wID
  788. * nBitmaps
  789. * hBMInst
  790. * wBMID
  791. * lpButtons
  792. * iNumButtons
  793. *
  794. * RETURNS
  795. * Success: handle to the tool bar control
  796. * Failure: 0
  797. *
  798. * NOTES
  799. * Do not use this functions anymore. Use CreateToolbarEx instead.
  800. */
  801. HWND WINAPI
  802. CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
  803. HINSTANCE hBMInst, UINT wBMID,
  804. LPCTBBUTTON lpButtons,INT iNumButtons)
  805. {
  806. return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
  807. hBMInst, wBMID, lpButtons,
  808. iNumButtons, 0, 0, 0, 0, CCSIZEOF_STRUCT(TBBUTTON, dwData));
  809. }
  810. /***********************************************************************
  811. * DllGetVersion [COMCTL32.@]
  812. *
  813. * Retrieves version information of the 'COMCTL32.DLL'
  814. *
  815. * PARAMS
  816. * pdvi [O] pointer to version information structure.
  817. *
  818. * RETURNS
  819. * Success: S_OK
  820. * Failure: E_INVALIDARG
  821. *
  822. * NOTES
  823. * Returns version of a comctl32.dll from IE4.01 SP1.
  824. */
  825. HRESULT WINAPI DllGetVersion (DLLVERSIONINFO *pdvi)
  826. {
  827. if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
  828. WARN("wrong DLLVERSIONINFO size from app\n");
  829. return E_INVALIDARG;
  830. }
  831. pdvi->dwMajorVersion = COMCTL32_VERSION;
  832. pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;
  833. pdvi->dwBuildNumber = 2919;
  834. pdvi->dwPlatformID = 6304;
  835. TRACE("%lu.%lu.%lu.%lu\n",
  836. pdvi->dwMajorVersion, pdvi->dwMinorVersion,
  837. pdvi->dwBuildNumber, pdvi->dwPlatformID);
  838. return S_OK;
  839. }
  840. /***********************************************************************
  841. * DllInstall (COMCTL32.@)
  842. *
  843. * Installs the ComCtl32 DLL.
  844. *
  845. * RETURNS
  846. * Success: S_OK
  847. * Failure: A HRESULT error
  848. */
  849. HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
  850. {
  851. FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
  852. debugstr_w(cmdline));
  853. return S_OK;
  854. }
  855. /***********************************************************************
  856. * _TrackMouseEvent [COMCTL32.@]
  857. *
  858. * Requests notification of mouse events
  859. *
  860. * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
  861. * to the hwnd specified in the ptme structure. After the event message
  862. * is posted to the hwnd, the entry in the queue is removed.
  863. *
  864. * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
  865. * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
  866. * immediately and the TME_LEAVE flag being ignored.
  867. *
  868. * PARAMS
  869. * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
  870. *
  871. * RETURNS
  872. * Success: non-zero
  873. * Failure: zero
  874. *
  875. * IMPLEMENTATION moved to USER32.TrackMouseEvent
  876. *
  877. */
  878. BOOL WINAPI
  879. _TrackMouseEvent (TRACKMOUSEEVENT *ptme)
  880. {
  881. return TrackMouseEvent (ptme);
  882. }
  883. /*************************************************************************
  884. * GetMUILanguage [COMCTL32.@]
  885. *
  886. * Returns the user interface language in use by the current process.
  887. *
  888. * RETURNS
  889. * Language ID in use by the current process.
  890. */
  891. LANGID WINAPI GetMUILanguage (VOID)
  892. {
  893. return COMCTL32_uiLang;
  894. }
  895. /*************************************************************************
  896. * InitMUILanguage [COMCTL32.@]
  897. *
  898. * Sets the user interface language to be used by the current process.
  899. *
  900. * RETURNS
  901. * Nothing.
  902. */
  903. VOID WINAPI InitMUILanguage (LANGID uiLang)
  904. {
  905. COMCTL32_uiLang = uiLang;
  906. }
  907. /***********************************************************************
  908. * SetWindowSubclass [COMCTL32.410]
  909. *
  910. * Starts a window subclass
  911. *
  912. * PARAMS
  913. * hWnd [in] handle to window subclass.
  914. * pfnSubclass [in] Pointer to new window procedure.
  915. * uIDSubclass [in] Unique identifier of sublass together with pfnSubclass.
  916. * dwRef [in] Reference data to pass to window procedure.
  917. *
  918. * RETURNS
  919. * Success: non-zero
  920. * Failure: zero
  921. *
  922. * BUGS
  923. * If an application manually subclasses a window after subclassing it with
  924. * this API and then with this API again, then none of the previous
  925. * subclasses get called or the origional window procedure.
  926. */
  927. BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
  928. UINT_PTR uIDSubclass, DWORD_PTR dwRef)
  929. {
  930. LPSUBCLASS_INFO stack;
  931. LPSUBCLASSPROCS proc;
  932. TRACE ("(%p, %p, %x, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);
  933. /* Since the window procedure that we set here has two additional arguments,
  934. * we can't simply set it as the new window procedure of the window. So we
  935. * set our own window procedure and then calculate the other two arguments
  936. * from there. */
  937. /* See if we have been called for this window */
  938. stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);
  939. if (!stack) {
  940. /* allocate stack */
  941. stack = Alloc (sizeof(SUBCLASS_INFO));
  942. if (!stack) {
  943. ERR ("Failed to allocate our Subclassing stack\n");
  944. return FALSE;
  945. }
  946. SetPropW (hWnd, COMCTL32_wSubclass, (HANDLE)stack);
  947. /* set window procedure to our own and save the current one */
  948. if (IsWindowUnicode (hWnd))
  949. stack->origproc = (WNDPROC)SetWindowLongPtrW (hWnd, GWLP_WNDPROC,
  950. (DWORD_PTR)COMCTL32_SubclassProc);
  951. else
  952. stack->origproc = (WNDPROC)SetWindowLongPtrA (hWnd, GWLP_WNDPROC,
  953. (DWORD_PTR)COMCTL32_SubclassProc);
  954. }
  955. else {
  956. /* Check to see if we have called this function with the same uIDSubClass
  957. * and pfnSubclass */
  958. proc = stack->SubclassProcs;
  959. while (proc) {
  960. if ((proc->id == uIDSubclass) &&
  961. (proc->subproc == pfnSubclass)) {
  962. proc->ref = dwRef;
  963. return TRUE;
  964. }
  965. proc = proc->next;
  966. }
  967. }
  968. proc = Alloc(sizeof(SUBCLASSPROCS));
  969. if (!proc) {
  970. ERR ("Failed to allocate subclass entry in stack\n");
  971. if (IsWindowUnicode (hWnd))
  972. SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
  973. else
  974. SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
  975. Free (stack);
  976. RemovePropW( hWnd, COMCTL32_wSubclass );
  977. return FALSE;
  978. }
  979. proc->subproc = pfnSubclass;
  980. proc->ref = dwRef;
  981. proc->id = uIDSubclass;
  982. proc->next = stack->SubclassProcs;
  983. stack->SubclassProcs = proc;
  984. return TRUE;
  985. }
  986. /***********************************************************************
  987. * GetWindowSubclass [COMCTL32.411]
  988. *
  989. * Gets the Reference data from a subclass.
  990. *
  991. * PARAMS
  992. * hWnd [in] Handle to window which were subclassing
  993. * pfnSubclass [in] Pointer to the subclass procedure
  994. * uID [in] Unique indentifier of the subclassing procedure
  995. * pdwRef [out] Pointer to the reference data
  996. *
  997. * RETURNS
  998. * Success: Non-zero
  999. * Failure: 0
  1000. */
  1001. BOOL WINAPI GetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
  1002. UINT_PTR uID, DWORD_PTR *pdwRef)
  1003. {
  1004. LPSUBCLASS_INFO stack;
  1005. LPSUBCLASSPROCS proc;
  1006. TRACE ("(%p, %p, %x, %p)\n", hWnd, pfnSubclass, uID, pdwRef);
  1007. /* See if we have been called for this window */
  1008. stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);
  1009. if (!stack)
  1010. return FALSE;
  1011. proc = stack->SubclassProcs;
  1012. while (proc) {
  1013. if ((proc->id == uID) &&
  1014. (proc->subproc == pfnSubclass)) {
  1015. *pdwRef = proc->ref;
  1016. return TRUE;
  1017. }
  1018. proc = proc->next;
  1019. }
  1020. return FALSE;
  1021. }
  1022. /***********************************************************************
  1023. * RemoveWindowSubclass [COMCTL32.412]
  1024. *
  1025. * Removes a window subclass.
  1026. *
  1027. * PARAMS
  1028. * hWnd [in] Handle to the window were subclassing
  1029. * pfnSubclass [in] Pointer to the subclass procedure
  1030. * uID [in] Unique identifier of this subclass
  1031. *
  1032. * RETURNS
  1033. * Success: non-zero
  1034. * Failure: zero
  1035. */
  1036. BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
  1037. {
  1038. LPSUBCLASS_INFO stack;
  1039. LPSUBCLASSPROCS prevproc = NULL;
  1040. LPSUBCLASSPROCS proc;
  1041. BOOL ret = FALSE;
  1042. TRACE ("(%p, %p, %x)\n", hWnd, pfnSubclass, uID);
  1043. /* Find the Subclass to remove */
  1044. stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);
  1045. if (!stack)
  1046. return FALSE;
  1047. proc = stack->SubclassProcs;
  1048. while (proc) {
  1049. if ((proc->id == uID) &&
  1050. (proc->subproc == pfnSubclass)) {
  1051. if (!prevproc)
  1052. stack->SubclassProcs = proc->next;
  1053. else
  1054. prevproc->next = proc->next;
  1055. if (stack->stackpos == proc)
  1056. stack->stackpos = stack->stackpos->next;
  1057. Free (proc);
  1058. ret = TRUE;
  1059. break;
  1060. }
  1061. prevproc = proc;
  1062. proc = proc->next;
  1063. }
  1064. if (!stack->SubclassProcs && !stack->running) {
  1065. TRACE("Last Subclass removed, cleaning up\n");
  1066. /* clean up our heap and reset the origional window procedure */
  1067. if (IsWindowUnicode (hWnd))
  1068. SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
  1069. else
  1070. SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
  1071. Free (stack);
  1072. RemovePropW( hWnd, COMCTL32_wSubclass );
  1073. }
  1074. return ret;
  1075. }
  1076. /***********************************************************************
  1077. * COMCTL32_SubclassProc (internal)
  1078. *
  1079. * Window procedure for all subclassed windows.
  1080. * Saves the current subclassing stack position to support nested messages
  1081. */
  1082. LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1083. {
  1084. LPSUBCLASS_INFO stack;
  1085. LPSUBCLASSPROCS proc;
  1086. LRESULT ret;
  1087. TRACE ("(%p, 0x%08x, 0x%08x, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);
  1088. stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);
  1089. if (!stack) {
  1090. ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
  1091. return 0;
  1092. }
  1093. /* Save our old stackpos to properly handle nested messages */
  1094. proc = stack->stackpos;
  1095. stack->stackpos = stack->SubclassProcs;
  1096. stack->running++;
  1097. ret = DefSubclassProc(hWnd, uMsg, wParam, lParam);
  1098. stack->running--;
  1099. stack->stackpos = proc;
  1100. if (!stack->SubclassProcs && !stack->running) {
  1101. TRACE("Last Subclass removed, cleaning up\n");
  1102. /* clean up our heap and reset the origional window procedure */
  1103. if (IsWindowUnicode (hWnd))
  1104. SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
  1105. else
  1106. SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
  1107. Free (stack);
  1108. RemovePropW( hWnd, COMCTL32_wSubclass );
  1109. }
  1110. return ret;
  1111. }
  1112. /***********************************************************************
  1113. * DefSubclassProc [COMCTL32.413]
  1114. *
  1115. * Calls the next window procedure (ie. the one before this subclass)
  1116. *
  1117. * PARAMS
  1118. * hWnd [in] The window that we're subclassing
  1119. * uMsg [in] Message
  1120. * wParam [in] WPARAM
  1121. * lParam [in] LPARAM
  1122. *
  1123. * RETURNS
  1124. * Success: non-zero
  1125. * Failure: zero
  1126. */
  1127. LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1128. {
  1129. LPSUBCLASS_INFO stack;
  1130. LRESULT ret;
  1131. TRACE ("(%p, 0x%08x, 0x%08x, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);
  1132. /* retrieve our little stack from the Properties */
  1133. stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);
  1134. if (!stack) {
  1135. ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
  1136. return 0;
  1137. }
  1138. /* If we are at the end of stack then we have to call the original
  1139. * window procedure */
  1140. if (!stack->stackpos) {
  1141. if (IsWindowUnicode (hWnd))
  1142. ret = CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam);
  1143. else
  1144. ret = CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);
  1145. } else {
  1146. LPSUBCLASSPROCS proc = stack->stackpos;
  1147. stack->stackpos = stack->stackpos->next;
  1148. /* call the Subclass procedure from the stack */
  1149. ret = proc->subproc (hWnd, uMsg, wParam, lParam,
  1150. proc->id, proc->ref);
  1151. }
  1152. return ret;
  1153. }
  1154. /***********************************************************************
  1155. * COMCTL32_CreateToolTip [NOT AN API]
  1156. *
  1157. * Creates a tooltip for the control specified in hwnd and does all
  1158. * necessary setup and notifications.
  1159. *
  1160. * PARAMS
  1161. * hwndOwner [I] Handle to the window that will own the tool tip.
  1162. *
  1163. * RETURNS
  1164. * Success: Handle of tool tip window.
  1165. * Failure: NULL
  1166. */
  1167. HWND
  1168. COMCTL32_CreateToolTip(HWND hwndOwner)
  1169. {
  1170. HWND hwndToolTip;
  1171. hwndToolTip = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, 0,
  1172. CW_USEDEFAULT, CW_USEDEFAULT,
  1173. CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,
  1174. 0, 0, 0);
  1175. /* Send NM_TOOLTIPSCREATED notification */
  1176. if (hwndToolTip)
  1177. {
  1178. NMTOOLTIPSCREATED nmttc;
  1179. /* true owner can be different if hwndOwner is a child window */
  1180. HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);
  1181. nmttc.hdr.hwndFrom = hwndTrueOwner;
  1182. nmttc.hdr.idFrom = GetWindowLongPtrW(hwndTrueOwner, GWLP_ID);
  1183. nmttc.hdr.code = NM_TOOLTIPSCREATED;
  1184. nmttc.hwndToolTips = hwndToolTip;
  1185. SendMessageW(GetParent(hwndTrueOwner), WM_NOTIFY,
  1186. (WPARAM)GetWindowLongPtrW(hwndTrueOwner, GWLP_ID),
  1187. (LPARAM)&nmttc);
  1188. }
  1189. return hwndToolTip;
  1190. }
  1191. /***********************************************************************
  1192. * COMCTL32_RefreshSysColors [NOT AN API]
  1193. *
  1194. * Invoked on any control recognizing a WM_SYSCOLORCHANGE message to
  1195. * refresh the color values in the color structure
  1196. *
  1197. * PARAMS
  1198. * none
  1199. *
  1200. * RETURNS
  1201. * none
  1202. */
  1203. VOID
  1204. COMCTL32_RefreshSysColors(void)
  1205. {
  1206. comctl32_color.clrBtnHighlight = GetSysColor (COLOR_BTNHIGHLIGHT);
  1207. comctl32_color.clrBtnShadow = GetSysColor (COLOR_BTNSHADOW);
  1208. comctl32_color.clrBtnText = GetSysColor (COLOR_BTNTEXT);
  1209. comctl32_color.clrBtnFace = GetSysColor (COLOR_BTNFACE);
  1210. comctl32_color.clrHighlight = GetSysColor (COLOR_HIGHLIGHT);
  1211. comctl32_color.clrHighlightText = GetSysColor (COLOR_HIGHLIGHTTEXT);
  1212. comctl32_color.clr3dHilight = GetSysColor (COLOR_3DHILIGHT);
  1213. comctl32_color.clr3dShadow = GetSysColor (COLOR_3DSHADOW);
  1214. comctl32_color.clr3dDkShadow = GetSysColor (COLOR_3DDKSHADOW);
  1215. comctl32_color.clr3dFace = GetSysColor (COLOR_3DFACE);
  1216. comctl32_color.clrWindow = GetSysColor (COLOR_WINDOW);
  1217. comctl32_color.clrWindowText = GetSysColor (COLOR_WINDOWTEXT);
  1218. comctl32_color.clrGrayText = GetSysColor (COLOR_GRAYTEXT);
  1219. comctl32_color.clrActiveCaption = GetSysColor (COLOR_ACTIVECAPTION);
  1220. comctl32_color.clrInfoBk = GetSysColor (COLOR_INFOBK);
  1221. comctl32_color.clrInfoText = GetSysColor (COLOR_INFOTEXT);
  1222. }
  1223. /***********************************************************************
  1224. * COMCTL32_DrawInsertMark [NOT AN API]
  1225. *
  1226. * Draws an insertion mark (which looks similar to an 'I').
  1227. *
  1228. * PARAMS
  1229. * hDC [I] Device context to draw onto.
  1230. * lpRect [I] Co-ordinates of insertion mark.
  1231. * clrInsertMark [I] Colour of the insertion mark.
  1232. * bHorizontal [I] True if insert mark should be drawn horizontally,
  1233. * vertical otherwise.
  1234. *
  1235. * RETURNS
  1236. * none
  1237. *
  1238. * NOTES
  1239. * Draws up to but not including the bottom co-ordinate when drawing
  1240. * vertically or the right co-ordinate when horizontal.
  1241. */
  1242. void COMCTL32_DrawInsertMark(HDC hDC, const RECT *lpRect, COLORREF clrInsertMark, BOOL bHorizontal)
  1243. {
  1244. HPEN hPen = CreatePen(PS_SOLID, 1, clrInsertMark);
  1245. HPEN hOldPen;
  1246. static const DWORD adwPolyPoints[] = {4,4,4};
  1247. LONG lCentre = (bHorizontal ?
  1248. lpRect->top + (lpRect->bottom - lpRect->top)/2 :
  1249. lpRect->left + (lpRect->right - lpRect->left)/2);
  1250. LONG l1 = (bHorizontal ? lpRect->left : lpRect->top);
  1251. LONG l2 = (bHorizontal ? lpRect->right : lpRect->bottom);
  1252. const POINT aptInsertMark[] =
  1253. {
  1254. /* top (V) or left (H) arrow */
  1255. {lCentre , l1 + 2},
  1256. {lCentre - 2, l1 },
  1257. {lCentre + 3, l1 },
  1258. {lCentre + 1, l1 + 2},
  1259. /* middle line */
  1260. {lCentre , l2 - 2},
  1261. {lCentre , l1 - 1},
  1262. {lCentre + 1, l1 - 1},
  1263. {lCentre + 1, l2 - 2},
  1264. /* bottom (V) or right (H) arrow */
  1265. {lCentre , l2 - 3},
  1266. {lCentre - 2, l2 - 1},
  1267. {lCentre + 3, l2 - 1},
  1268. {lCentre + 1, l2 - 3},
  1269. };
  1270. hOldPen = SelectObject(hDC, hPen);
  1271. PolyPolyline(hDC, aptInsertMark, adwPolyPoints, sizeof(adwPolyPoints)/sizeof(adwPolyPoints[0]));
  1272. SelectObject(hDC, hOldPen);
  1273. DeleteObject(hPen);
  1274. }
  1275. /***********************************************************************
  1276. * MirrorIcon [COMCTL32.414]
  1277. *
  1278. * Mirrors an icon so that it will appear correctly on a mirrored DC.
  1279. *
  1280. * PARAMS
  1281. * phicon1 [I/O] Icon.
  1282. * phicon2 [I/O] Icon.
  1283. *
  1284. * RETURNS
  1285. * Success: TRUE.
  1286. * Failure: FALSE.
  1287. */
  1288. BOOL WINAPI MirrorIcon(HICON *phicon1, HICON *phicon2)
  1289. {
  1290. FIXME("(%p, %p): stub\n", phicon1, phicon2);
  1291. return FALSE;
  1292. }
  1293. static inline int IsDelimiter(WCHAR c)
  1294. {
  1295. switch(c)
  1296. {
  1297. case '/':
  1298. case '\\':
  1299. case '.':
  1300. case ' ':
  1301. return TRUE;
  1302. }
  1303. return FALSE;
  1304. }
  1305. static int CALLBACK PathWordBreakProc(LPWSTR lpch, int ichCurrent, int cch, int code)
  1306. {
  1307. if (code == WB_ISDELIMITER)
  1308. return IsDelimiter(lpch[ichCurrent]);
  1309. else
  1310. {
  1311. int dir = (code == WB_LEFT) ? -1 : 1;
  1312. for(; 0 <= ichCurrent && ichCurrent < cch; ichCurrent += dir)
  1313. if (IsDelimiter(lpch[ichCurrent])) return ichCurrent;
  1314. }
  1315. return ichCurrent;
  1316. }
  1317. /***********************************************************************
  1318. * SetPathWordBreakProc [COMCTL32.384]
  1319. *
  1320. * Sets the word break procedure for an edit control to one that understands
  1321. * paths so that the user can jump over directories.
  1322. *
  1323. * PARAMS
  1324. * hwnd [I] Handle to edit control.
  1325. * bSet [I] If this is TRUE then the word break proc is set, otherwise it is removed.
  1326. *
  1327. * RETURNS
  1328. * Result from EM_SETWORDBREAKPROC message.
  1329. */
  1330. LRESULT WINAPI SetPathWordBreakProc(HWND hwnd, BOOL bSet)
  1331. {
  1332. return SendMessageW(hwnd, EM_SETWORDBREAKPROC, 0,
  1333. (LPARAM)(bSet ? PathWordBreakProc : NULL));
  1334. }