win_win32.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:68k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: win_win32.c 623 2006-02-01 13:19:15Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../../common/common.h"
  24. #include "../win.h"
  25. #include "widcommaudio.h"
  26. #include "querykey_win32.h"
  27. #include "openfile_win32.h"
  28. #include "playlst.h"
  29. #include "interface.h"
  30. #if defined(TARGET_WINCE) || defined(TARGET_WIN32)
  31. #define WIN32_LEAN_AND_MEAN
  32. #ifndef STRICT
  33. #define STRICT
  34. #endif
  35. #include <windows.h>
  36. #if _MSC_VER > 1000
  37. #pragma warning(disable : 4201)
  38. #endif
  39. #include <commctrl.h>
  40. #include <shellapi.h>
  41. #include "resource.h"
  42. #define MAXFONTSIZE 64
  43. static HFONT FontCache[MAXFONTSIZE][2];
  44. static WNDCLASS WinClass;
  45. static WNDCLASS DialogClass;
  46. static tchar_t WinClassName[64];
  47. static win* Main = NULL;
  48. #ifndef GCL_HMODULE         
  49. #define GCL_HMODULE         (-16)
  50. #endif
  51. #ifndef UDS_EXPANDABLE
  52. #define UDS_EXPANDABLE  0x0200
  53. #endif
  54. #if defined(TARGET_WINCE)
  55. #define DIALOG_COLOR COLOR_STATIC
  56. #else
  57. #define DIALOG_COLOR COLOR_BTNFACE
  58. #define MOD_KEYUP 0
  59. #endif
  60. #define VALIDCONTROL(i) ((int)(i) & ~0xFFFF)
  61. #define TRACKMAX 30000
  62. #define TRACKTHUMB 9
  63. static BOOL (WINAPI* FuncUnregisterFunc1)( int Flags,int HoyKey ) = NULL;
  64. static BOOL (WINAPI* FuncAllKeys)( int State ) = NULL;
  65. #define TOOLBAR_ID 1000
  66. #if !defined(TARGET_WINCE)
  67. #define TBSTYLE_EX_MIXEDBUTTONS         0x00000008
  68. #ifndef BTNS_SHOWTEXT
  69. #define BTNS_SHOWTEXT 0x40
  70. #endif
  71. #else
  72. #define BTNS_SHOWTEXT 0
  73. #endif
  74. static const menudef* MenuDef(win* Win,const menudef* p,bool_t Popup,void** Menu)
  75. {
  76. int Level = p->Level;
  77. if (!*Menu)
  78. *Menu = Popup ? CreatePopupMenu() : CreateMenu();
  79. while (p->Level==Level && Level>=0)
  80. {
  81. bool_t Skip = 0;
  82. if (p->Id==-1)
  83. {
  84. if (!Win->MenuSmall && !Skip)
  85. AppendMenu(*Menu,MF_SEPARATOR,0,NULL);
  86. ++p;
  87. }
  88. else
  89. {
  90. tchar_t s[256];
  91. int Flags = MF_STRING;
  92. int Id = p->Id;
  93. tcscpy_s(s,TSIZEOF(s),LangStr(p->Class,p->Id));
  94. if (p->Class == PLATFORM_ID)
  95. {
  96. if (p->Level==0 && p->Id == PLATFORM_CANCEL && Win->TitleCancel)
  97. {
  98. ++p;
  99. continue;
  100. }
  101. if (p->Id == PLATFORM_OK)
  102. {
  103. Win->NeedOK = 1;
  104. if (Win->TitleOK)
  105. {
  106. ++p;
  107. continue;
  108. }
  109. }
  110. if (p->Id == PLATFORM_DONE)
  111. {
  112. Win->NeedOK = 1;
  113. if (Win->TitleDone)
  114. {
  115. ++p;
  116. continue;
  117. }
  118. }
  119. }
  120. ++p;
  121. if (p->Level > Level)
  122. {
  123. if (((p[-1].Flags & MENU_SMALL) && !Win->MenuSmall) ||
  124. ((p[-1].Flags & MENU_NOTSMALL) && Win->MenuSmall))
  125. {
  126. if (p[-1].Flags & MENU_GRAYED)
  127. {
  128. AppendMenu(*Menu,Flags,Id,s);
  129. EnableMenuItem(*Menu,Id,MF_GRAYED|MF_BYCOMMAND);
  130. }
  131. // skip
  132. p = MenuDef(Win,p,1,Menu);
  133. continue;
  134. }
  135. else
  136. if (p[-1].Flags & MENU_GRAYED)
  137. int i = tcslen(s);
  138. if (i && s[i-1]==':')
  139. s[i-1] = 0;
  140. }
  141. Id = 0;
  142. p = MenuDef(Win,p,1,(HMENU*)&Id);
  143. Flags |= MF_POPUP;
  144. }
  145. if (!Skip)
  146. {
  147. AppendMenu(*Menu,Flags,Id,s);
  148. if (!(Flags & MF_POPUP) && (p[-1].Flags & MENU_GRAYED))
  149. EnableMenuItem(*Menu,Id,MF_GRAYED|MF_BYCOMMAND);
  150. }
  151. else
  152. {
  153. if (Flags & MF_POPUP)
  154. DestroyMenu((HMENU)Id);
  155. }
  156. }
  157. }
  158. return p;
  159. }
  160. #if defined(TARGET_WINCE)
  161. #define SIPF_OFF 0x00000000
  162. #define SIPF_ON  0x00000001
  163. typedef struct SHACTIVATEINFO
  164. {
  165. DWORD cbSize;
  166. HWND hwndLastFocus;
  167. UINT fSipUp:1;
  168. UINT fSipOnDeactivation:1;
  169. UINT fActive:1;
  170. UINT fReserved:29;
  171. } SHACTIVATEINFO;
  172. #define SHMBOF_NODEFAULT    0x00000001
  173. #define SHMBOF_NOTIFY       0x00000002
  174. #define SHCMBM_GETSUBMENU (WM_USER + 401)
  175. #define SHCMBM_GETMENU      (WM_USER + 402)
  176. #define SHCMBM_OVERRIDEKEY  (WM_USER + 403)
  177. #define SHCMBF_EMPTYBAR      0x0001
  178. #define SHCMBF_HIDDEN        0x0002
  179. #define SHCMBF_HIDESIPBUTTON 0x0004
  180. #define SHCMBF_COLORBK       0x0008
  181. #define SHCMBF_HMENU         0x0010
  182. typedef struct SHMENUBARINFO
  183. {
  184.     DWORD cbSize;
  185. HWND hwndParent;
  186.     DWORD dwFlags;
  187.     UINT nToolBarId;
  188.     HINSTANCE hInstRes;
  189.     int nBmpId;
  190.     int cBmpImages;
  191. HWND hwndMB;
  192.     // COLORREF clrBk; //be as compatible as possible
  193. } SHMENUBARINFO;
  194. #define SHIDIM_FLAGS 0x0001 
  195. #define SHIDIF_DONEBUTTON           0x0001
  196. #define SHIDIF_SIZEDLG              0x0002
  197. #define SHIDIF_SIZEDLGFULLSCREEN    0x0004
  198. #define SHIDIF_SIPDOWN              0x0008
  199. #define SHIDIF_FULLSCREENNOMENUBAR  0x0010
  200. #define SHIDIF_EMPTYMENU            0x0020
  201. typedef struct SHINITDLGINFO
  202. {
  203.     DWORD dwMask;
  204.     HWND  hDlg;
  205.     DWORD dwFlags;
  206. } SHINITDLGINFO;
  207. #define SPI_GETSIPINFO          225
  208. #define SPI_APPBUTTONCHANGE     228
  209. typedef struct SIPINFO
  210. {
  211.     DWORD   cbSize;
  212.     DWORD   fdwFlags;
  213.     RECT    rcVisibleDesktop;
  214.     RECT    rcSipRect;
  215.     DWORD   dwImDataSize;
  216.     void   *pvImData;
  217. } SIPINFO;
  218. #define SHFS_SHOWTASKBAR            0x0001
  219. #define SHFS_HIDETASKBAR            0x0002
  220. #define SHFS_SHOWSIPBUTTON          0x0004
  221. #define SHFS_HIDESIPBUTTON          0x0008
  222. #define SHFS_SHOWSTARTICON          0x0010
  223. #define SHFS_HIDESTARTICON          0x0020
  224. static HMODULE AygShell = NULL;
  225. static HMODULE CoreDLL = NULL;
  226. static BOOL (WINAPI* FuncSipGetInfo)(SIPINFO *pSipInfo) = NULL;
  227. static BOOL (WINAPI* FuncSipShowIM)(DWORD) = NULL;
  228. static BOOL (WINAPI* FuncSHCreateMenuBar)( SHMENUBARINFO *pmb ) = NULL;
  229. static BOOL (WINAPI* FuncSHInitDialog)( SHINITDLGINFO *shdi ) = NULL;
  230. static BOOL (WINAPI* FuncSHFullScreen)( HWND, DWORD ) = NULL;
  231. static BOOL (WINAPI* FuncSHHandleWMActivate)( HWND, WPARAM, LPARAM, void*, DWORD ) = NULL;
  232. static BOOL (WINAPI* FuncSHHandleWMSettingChange)(HWND, WPARAM, LPARAM, void*) = NULL;
  233. static BOOL (WINAPI* FuncSHSendBackToFocusWindow)(UINT, WPARAM, LPARAM ) = NULL;
  234. static bool_t HHTaskbarTop = 0;
  235. static bool_t TaskBarHidden = 0;
  236. void MergeRect(RECT* r,HWND Wnd)
  237. {
  238. if (Wnd)
  239. {
  240. RECT a;
  241. GetWindowRect(Wnd,&a);
  242. if (a.bottom == r->top)
  243. r->top = a.top;
  244. if (a.top == r->bottom)
  245. r->bottom = a.bottom;
  246. }
  247. }
  248. void GetWorkArea(win* p,RECT* r)
  249. {
  250. SystemParametersInfo(SPI_GETWORKAREA,0,r,0);
  251. if (p->AygShellTB && p->WndTB)
  252. {
  253. RECT RectTB;
  254. GetWindowRect(p->WndTB, &RectTB);
  255. if (r->bottom > RectTB.top)
  256. r->bottom = RectTB.top;
  257. }
  258. if (TaskBarHidden)
  259. {
  260. MergeRect(r,FindWindow(T("HHTaskbar"),NULL));
  261. MergeRect(r,FindWindow(T("Tray"),NULL));
  262. }
  263. }
  264. void DIASet(int State,int Mask)
  265. {
  266. if ((Mask & DIA_SIP) && FuncSipShowIM)
  267. FuncSipShowIM((State & DIA_SIP)?SIPF_ON:SIPF_OFF);
  268. if (Mask & DIA_TASKBAR)
  269. {
  270. bool_t Hidden = !(State & DIA_TASKBAR);
  271. if (Hidden != TaskBarHidden)
  272. {
  273. win* p;
  274. HWND WndTaskbar = FindWindow(T("HHTaskbar"),NULL);
  275. HWND WndTray = FindWindow(T("Tray"),NULL); //for smartphone
  276. TaskBarHidden = Hidden;
  277. if (WndTaskbar)
  278. ShowWindow(WndTaskbar,Hidden ? SW_HIDE:SW_SHOWNA);
  279. if (WndTray)
  280. ShowWindow(WndTray,Hidden ? SW_HIDE:SW_SHOWNA);
  281. for (p=Main;p;p=p->Child)
  282. {
  283. if (FuncSHFullScreen)
  284. FuncSHFullScreen(p->Wnd,Hidden ? SHFS_HIDETASKBAR : SHFS_SHOWTASKBAR);
  285. if (!p->FullScreen)
  286. {
  287. RECT r;
  288. GetWorkArea(p,&r);
  289. SetWindowPos(p->Wnd,NULL, r.left, r.top, r.right-r.left, r.bottom-r.top, SWP_NOZORDER);
  290. }
  291. else
  292. {
  293. p->SaveScreen.x = GetSystemMetrics(SM_CXSCREEN);
  294. p->SaveScreen.y = GetSystemMetrics(SM_CYSCREEN);
  295. GetWorkArea(p,(RECT*)&p->SaveRect);
  296. }
  297. }
  298. }
  299. }
  300. }
  301. int DIAGet(int Mask)
  302. {
  303. int Value = 0;
  304. if ((Mask & DIA_TASKBAR) && !TaskBarHidden)
  305. Value |= DIA_TASKBAR;
  306. if ((Mask & DIA_SIP) && FuncSipGetInfo)
  307. {
  308. SIPINFO Info;
  309. Info.cbSize = sizeof(Info);
  310. if (FuncSipGetInfo(&Info) && (Info.fdwFlags & SIPF_ON))
  311. Value |= DIA_SIP;
  312. }
  313. return Value;
  314. }
  315. void WinSetFullScreen(win* p,bool_t State)
  316. {
  317. if (State != p->FullScreen)
  318. {
  319. // no need to hide HHTaskbar because we use TOPMOST and with aygshell we use SHFS_HIDETASKBAR
  320. HWND WndTaskbar = FindWindow(T("HHTaskbar"),NULL);
  321. HWND WndTray = FindWindow(T("Tray"),NULL); //for smartphone
  322. DEBUG_MSG1(DEBUG_WIN,T("FULLSCREEN %d"),State);
  323. p->FullScreen = State; // set flag before SetWindowPos so WM_SIZE,WM_MOVE has valid info
  324. if (State)
  325. {
  326. HWND Mode;
  327. if (FuncSHFullScreen)
  328. {
  329. Mode = HWND_TOP; //incoming calls on smartphones doesn't like topmost
  330. FuncSHFullScreen(p->Wnd,SHFS_HIDETASKBAR);
  331. FuncSHFullScreen(p->Wnd,SHFS_HIDESIPBUTTON);
  332. }
  333. else
  334. {
  335. Mode = HWND_TOPMOST;
  336. if (WndTaskbar)
  337. {
  338. RECT r;
  339. GetWindowRect(WndTaskbar,&r);
  340. HHTaskbarTop = r.top == 0 && r.left == 0;
  341. if (HHTaskbarTop)
  342. ShowWindow(WndTaskbar,SW_HIDE); // old-style with pocketpc
  343. }
  344. }
  345. if (p->WndTB)
  346. ShowWindow(p->WndTB,SW_HIDE);
  347. if (WndTray)
  348. ShowWindow(WndTray,SW_HIDE);
  349. p->SaveScreen.x = GetSystemMetrics(SM_CXSCREEN);
  350. p->SaveScreen.y = GetSystemMetrics(SM_CYSCREEN);
  351. GetWindowRect(p->Wnd,(RECT*)&p->SaveRect);
  352. SetWindowPos(p->Wnd,Mode, 0, 0, p->SaveScreen.x,p->SaveScreen.y,0);
  353. ShowCursor(FALSE);
  354. SetKeyboardBacklight(0);
  355. }
  356. else
  357. {
  358. ShowCursor(TRUE);
  359. SetKeyboardBacklight(1);
  360. if (p->WndTB)
  361. ShowWindow(p->WndTB,SW_SHOWNA);
  362. p->SaveRect[2] += GetSystemMetrics(SM_CXSCREEN) - p->SaveScreen.x;
  363. p->SaveRect[3] += GetSystemMetrics(SM_CYSCREEN) - p->SaveScreen.y;
  364. SetWindowPos(p->Wnd,HWND_NOTOPMOST,p->SaveRect[0],p->SaveRect[1],
  365. p->SaveRect[2]-p->SaveRect[0],p->SaveRect[3]-p->SaveRect[1],SWP_NOACTIVATE);
  366. if (!TaskBarHidden)
  367. {
  368. if (FuncSHFullScreen)
  369. FuncSHFullScreen(p->Wnd,SHFS_SHOWTASKBAR);
  370. else
  371. if (WndTaskbar && HHTaskbarTop)
  372. ShowWindow(WndTaskbar,SW_SHOWNA); // old-style with pocketpc
  373. }
  374. if (WndTray && !TaskBarHidden)
  375. ShowWindow(WndTray,SW_SHOWNA);
  376. }
  377. }
  378. }
  379. static void DestroyToolBar(win* p)
  380. {
  381. if (p->WndTB)
  382. {
  383. CommandBar_Destroy(p->WndTB);
  384. p->WndTB = NULL;
  385. }
  386. }
  387. void WinBitmap(win* p,int BitmapId16, int BitmapId32, int BitmapNum)
  388. {
  389. if (p->WndTB)
  390. {
  391. if (p->LogPixelSX >= 96*2)
  392. p->BitmapNo = CommandBar_AddBitmap(p->WndTB,p->Module,BitmapId32,BitmapNum,32,32);
  393. else
  394. p->BitmapNo = CommandBar_AddBitmap(p->WndTB,p->Module,BitmapId16,BitmapNum,16,16);
  395. }
  396. }
  397. static const menudef* SkipButtons(win* p,const menudef* i)
  398. {
  399. while (i->Level==0)
  400. {
  401. bool_t Skip = 0;
  402. if (p->TitleOK && i->Class == PLATFORM_ID && i->Id == PLATFORM_OK)
  403. {
  404. p->NeedOK = 1;
  405. Skip = 1;
  406. }
  407. if (p->TitleDone && i->Class == PLATFORM_ID && i->Id == PLATFORM_DONE)
  408. {
  409. p->NeedOK = 1;
  410. Skip = 1;
  411. }
  412. if (!Skip)
  413. break;
  414. ++i;
  415. }
  416. return i;
  417. }
  418. static void AddButton(win* p,int Pos,int Id,int Bitmap,tchar_t* Name,bool_t Check);
  419. static void CreateToolBar(win* p)
  420. {
  421. int Ver = QueryPlatform(PLATFORM_VER);
  422. RECT Rect,RectTB;
  423. p->WndTB = NULL;
  424. p->Menu3 = NULL;
  425. memset(&p->Menu2,0,sizeof(p->Menu2));
  426. p->AygShellTB = 0;
  427. p->TitleCancel = p->Smartphone && (p->Flags & WIN_DIALOG);
  428. p->TitleOK = p->TitleDone = !p->Smartphone && !TaskBarHidden && Ver<500;
  429. p->NeedOK = 0;
  430. if (FuncSHCreateMenuBar)
  431. {
  432. SHMENUBARINFO Info;
  433. memset(&Info,0,sizeof(Info));
  434. Info.cbSize = sizeof(Info);
  435. if (p->Smartphone)
  436. Info.cbSize += sizeof(COLORREF); //clrBk
  437. Info.hwndParent = p->Wnd;
  438. Info.nToolBarId = 0;
  439. Info.hInstRes = p->Module;
  440. Info.dwFlags = 0;
  441. if (!p->MenuDef)
  442. Info.dwFlags |= SHCMBF_EMPTYBAR;
  443. else
  444. {
  445. const menudef* i = p->MenuDef;
  446. int Mode = 0;
  447. i = SkipButtons(p,i);
  448. if (i->Level==0)
  449. {
  450. ++i;
  451. for (;i->Level>0;++i)
  452. Mode |= 1;  // submenu under first menu
  453. }
  454. i = SkipButtons(p,i);
  455. if (i->Level==0)
  456. {
  457. ++i;
  458. for (;i->Level>0;++i)
  459. Mode |= 2;  // submenu under second menu
  460. }
  461. switch (Mode)
  462. {
  463. case 0: Info.nToolBarId = IDR_MENU00; break;
  464. case 1: Info.nToolBarId = IDR_MENU10; break;
  465. case 2: Info.nToolBarId = IDR_MENU01; break;
  466. case 3: Info.nToolBarId = IDR_MENU11; break;
  467. }
  468. }
  469. if (!(p->Flags & WIN_DIALOG))
  470. Info.dwFlags |= SHCMBF_HIDESIPBUTTON;
  471. FuncSHCreateMenuBar(&Info);
  472. p->WndTB = Info.hwndMB;
  473. p->ToolBarHeight = 0;
  474. GetWindowRect(p->Wnd, &Rect);
  475. if (p->WndTB)
  476. {
  477. if (p->MenuDef)
  478. {
  479. TBBUTTONINFO Button;
  480. const menudef* i = p->MenuDef;
  481. int No = 0;
  482. while (i->Level>=0)
  483. {
  484. i = SkipButtons(p,i);
  485. if (i->Level<0)
  486. break;
  487. if (No<2)
  488. {
  489. int Id = No ? WIN_B : WIN_A;
  490. p->WinCmd[No] = i->Id;
  491. Button.cbSize = sizeof(Button);
  492. Button.dwMask = TBIF_TEXT;
  493. Button.pszText = (tchar_t*)LangStr(i->Class,i->Id);
  494. SendMessage(p->WndTB,TB_SETBUTTONINFO,Id,(LPARAM)&Button);
  495. ++i;
  496. if (i->Level>0)
  497. {
  498. p->Menu2[No] = (HMENU)SendMessage(p->WndTB,SHCMBM_GETSUBMENU,0,No ? WIN_B:WIN_A);
  499. if (p->Menu2[No])
  500. {
  501. DeleteMenu(p->Menu2[No],No ? WIN_B_B:WIN_A_A,MF_BYCOMMAND);
  502. i = MenuDef(p,i,0,&p->Menu2[No]);
  503. }
  504. }
  505. if (No==1 && !p->Smartphone && Ver<500)
  506. {
  507. TBBUTTON Sep;
  508. memset(&Sep,0,sizeof(Sep));
  509. Sep.fsStyle = TBSTYLE_SEP;
  510. SendMessage(p->WndTB,TB_INSERTBUTTON,No,(LPARAM)&Sep);
  511. ++No;
  512. }
  513. }
  514. else
  515. {
  516. if (p->Smartphone) 
  517. break;
  518. AddButton(p,No,i->Id,-2,(tchar_t*)LangStr(i->Class,i->Id),0);
  519. ++i;
  520. assert(i->Level<=0); // no submenu allowed (only for WIN_A,WIN_B)
  521. }
  522. ++No;
  523. }
  524. while (!p->Smartphone && SendMessage(p->WndTB,TB_BUTTONCOUNT,0,0)>No)
  525. SendMessage(p->WndTB,TB_DELETEBUTTON,No,0);
  526. }
  527. GetWindowRect(p->WndTB, &RectTB);
  528. if (Rect.bottom > RectTB.top)
  529. Rect.bottom = RectTB.top;
  530. //Rect.bottom -= (RectTB.bottom - RectTB.top);
  531. MoveWindow(p->Wnd,Rect.left,Rect.top,Rect.right - Rect.left,Rect.bottom - Rect.top,0);
  532. p->AygShellTB = 1;
  533. p->Flags |= WIN_BOTTOMTOOLBAR;
  534. if (p->Smartphone)
  535. p->Flags |= WIN_2BUTTON;
  536. if (p->Flags & WIN_DIALOG)
  537. SendMessage(p->WndTB,SHCMBM_OVERRIDEKEY,VK_ESCAPE,
  538. MAKELONG(SHMBOF_NODEFAULT|SHMBOF_NOTIFY,SHMBOF_NODEFAULT|SHMBOF_NOTIFY));
  539. }
  540. }
  541. if (!p->WndTB)
  542. {
  543. p->TitleOK = p->TitleDone = !p->Smartphone;
  544. p->TitleCancel = 1;
  545. p->WndTB = CommandBar_Create(p->Module,p->Wnd,TOOLBAR_ID);
  546. p->ToolBarHeight = CommandBar_Height(p->WndTB);
  547. if (p->MenuDef)
  548. {
  549. MenuDef(p,p->MenuDef,0,&p->Menu3);
  550. p->Menu2[0] = p->Menu3;
  551. p->Menu2[1] = p->Menu3;
  552. CommandBar_InsertMenubarEx(p->WndTB,NULL,(tchar_t*)p->Menu3,0);
  553. }
  554. CommandBar_Show(p->WndTB, TRUE);
  555. }
  556. }
  557. #else
  558. static WNDPROC OldToolBarProc = NULL;
  559. static LRESULT CALLBACK ToolBarProc( HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam )
  560. {
  561. if (Msg == WM_MOUSEACTIVATE)
  562. return MA_NOACTIVATE;
  563. if (Msg == WM_LBUTTONUP)
  564. {
  565. int i;
  566. int n=SendMessage(Wnd,TB_BUTTONCOUNT,0,0);
  567. for (i=0;i<n;++i)
  568. {
  569. TBBUTTON Button;
  570. RECT r;
  571. POINT p;
  572. SendMessage(Wnd,TB_GETBUTTON,i,(LPARAM)&Button);
  573. if ((Button.fsState & TBSTATE_PRESSED))
  574. {
  575. if (IsMenu((HMENU)Button.dwData))
  576. {
  577. SendMessage(Wnd,TB_GETRECT,Button.idCommand,(LPARAM)&r);
  578. p.x = LOWORD(lParam);
  579. p.y = HIWORD(lParam);
  580. if (PtInRect(&r,p))
  581. {
  582. p.x = r.left;
  583. p.y = r.bottom;
  584. ClientToScreen(Wnd,&p);
  585. TrackPopupMenu((HMENU)Button.dwData,TPM_LEFTALIGN|TPM_TOPALIGN,
  586. p.x,p.y,0,GetParent(Wnd),NULL);
  587. }
  588. }
  589. }
  590. }
  591. }
  592. return CallWindowProc(OldToolBarProc,Wnd,Msg,wParam,lParam);
  593. }
  594. static void DestroyToolBar(win* p)
  595. {
  596. DestroyWindow(p->WndTB);
  597. p->WndTB = NULL;
  598. }
  599. static void AddMenu(win* p)
  600. {
  601. TBBUTTONINFO Info;
  602. TBBUTTON Button;
  603. tchar_t Name[256];
  604. int Pos;
  605. p->TitleCancel = 1;
  606. p->TitleOK = 0;
  607. p->TitleDone = 1;
  608. p->NeedOK = 0;
  609. p->Menu3 = NULL;
  610. memset(&p->Menu2,0,sizeof(p->Menu2));
  611. if (p->MenuDef)
  612. {
  613. MenuDef(p,p->MenuDef,0,&p->Menu3);
  614. p->Menu2[0] = p->Menu3;
  615. p->Menu2[1] = p->Menu3;
  616. for (Pos=0;Pos<GetMenuItemCount(p->Menu3);++Pos)
  617. {
  618. GetMenuString(p->Menu3,Pos,Name,255,MF_BYPOSITION);
  619. memset(&Button,0,sizeof(Button));
  620. Button.iBitmap = -2;
  621. Button.idCommand = GetMenuItemID(p->Menu3,Pos);
  622. if (Button.idCommand < 0)
  623. Button.idCommand = TOOLBAR_ID+Pos+1;
  624. Button.fsState = TBSTATE_ENABLED;
  625. Button.fsStyle = (BYTE)(TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE | BTNS_SHOWTEXT);
  626. if (!Button.idCommand)
  627. Button.fsStyle = TBSTYLE_SEP;
  628. Button.dwData = (DWORD) GetSubMenu(p->Menu3,Pos);
  629. Button.iString = 0;
  630. SendMessage(p->WndTB,TB_INSERTBUTTON,Pos,(LPARAM)&Button);
  631. Info.cbSize = sizeof(TBBUTTONINFO);
  632. Info.dwMask = TBIF_TEXT;
  633. Info.pszText = Name;
  634. SendMessage(p->WndTB,TB_SETBUTTONINFO,Button.idCommand,(LPARAM)&Info);
  635. }
  636. }
  637. SendMessage(p->WndTB,TB_AUTOSIZE,0,0);
  638. }
  639. void WinBitmap(win* p,int BitmapId16, int BitmapId32, int BitmapNum)
  640. {
  641. TBADDBITMAP Add;
  642. Add.hInst = p->Module;
  643. Add.nID = BitmapId16;
  644. p->BitmapNo = SendMessage(p->WndTB,TB_ADDBITMAP,BitmapNum,(LPARAM)&Add);
  645. }
  646. static void CreateToolBar(win* p)
  647. {
  648. RECT r;
  649. if ((p->Flags & WIN_NOMENU) == 0)
  650. {
  651. p->WndTB = CreateWindowEx(0, TOOLBARCLASSNAME, (LPCTSTR) NULL, 
  652. WS_CHILD|TBSTYLE_FLAT|TBSTYLE_LIST|WS_VISIBLE, 
  653. 0, 0, 0, 0, p->Wnd, (HMENU)TOOLBAR_ID, p->Module, NULL); 
  654. if (p->WndTB)
  655. {
  656. SendMessage(p->WndTB, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0); 
  657. SendMessage(p->WndTB,TB_SETEXTENDEDSTYLE,0,TBSTYLE_EX_MIXEDBUTTONS);
  658. OldToolBarProc = (WNDPROC) GetWindowLong(p->WndTB,GWL_WNDPROC);
  659. SetWindowLong(p->WndTB,GWL_WNDPROC,(LONG)ToolBarProc);
  660. GetWindowRect(p->WndTB,&r);
  661. p->ToolBarHeight = r.bottom - r.top;
  662. AddMenu(p);
  663. }
  664. }
  665. }
  666. void DIASet(int State,int Mask)
  667. {
  668. }
  669. int DIAGet(int Mask)
  670. {
  671. return DIA_TASKBAR & Mask;
  672. }
  673. void WinSetFullScreen(win* p,bool_t State)
  674. {
  675. if (State != p->FullScreen)
  676. {
  677. p->FullScreen = State;
  678. if (State)
  679. {
  680. p->SaveStyle = GetWindowLong(p->Wnd,GWL_STYLE);
  681. GetWindowRect(p->Wnd,(RECT*)&p->SaveRect);
  682. SetWindowLong(p->Wnd,GWL_STYLE,WS_TABSTOP|WS_VISIBLE|WS_POPUP|WS_GROUP);
  683. #ifdef NDEBUG
  684. SetWindowPos(p->Wnd,HWND_TOPMOST,0,0,
  685. #else
  686. SetWindowPos(p->Wnd,HWND_NOTOPMOST,0,0,
  687. #endif
  688. GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),SWP_FRAMECHANGED);
  689. }
  690. else
  691. {
  692. SetWindowLong(p->Wnd,GWL_STYLE,p->SaveStyle);
  693. SetWindowPos(p->Wnd,HWND_NOTOPMOST,p->SaveRect[0],p->SaveRect[1],
  694. p->SaveRect[2]-p->SaveRect[0],p->SaveRect[3]-p->SaveRect[1],SWP_FRAMECHANGED);
  695. }
  696. ShowWindow(p->WndTB,State ? SW_HIDE:SW_SHOWNA);
  697. InvalidateRect(p->Wnd,NULL,0);
  698. }
  699. }
  700. #endif
  701. static int GetDataDefType(wincontrol* i)
  702. {
  703. datadef DataDef;
  704. if (!NodeDataDef(i->Pin.Node,i->Pin.No,&DataDef))
  705. return 0;
  706. return DataDef.Type;
  707. }
  708. static void SetTrack(win* p,wincontrol* i,int Value)
  709. {
  710. tick_t Tick;
  711. datadef DataDef;
  712. if (!NodeDataDef(i->Pin.Node,i->Pin.No,&DataDef))
  713. return;
  714. if (DataDef.Format2 - DataDef.Format1 <= TRACKMAX)
  715. Value += DataDef.Format1;
  716. else
  717. Value = DataDef.Format1 + Scale(DataDef.Format2 - DataDef.Format1,Value,TRACKMAX);
  718. switch (DataDef.Type)
  719. {
  720. case TYPE_INT:
  721. i->Pin.Node->Set(i->Pin.Node,i->Pin.No,&Value,sizeof(Value));
  722. break;
  723. case TYPE_TICK:
  724. Tick = Value;
  725. i->Pin.Node->Set(i->Pin.Node,i->Pin.No,&Tick,sizeof(Tick));
  726. break;
  727. }
  728. }
  729. static void WinControlDisable(win* p,wincontrol* Control,bool_t v)
  730. {
  731. if (Control->Disabled != v)
  732. {
  733. wincontrol* i;
  734. Control->Disabled = v;
  735. if (Control->Control)
  736. EnableWindow(Control->Control,!v);
  737. if (Control->Edit)
  738. EnableWindow(Control->Edit,!v);
  739. for (i=p->Controls;i;i=i->Next)
  740. if (i->Ref == Control)
  741. EnableWindow(i->Control,!v);
  742. }
  743. }
  744. static void WinControlUpdate(win* p,wincontrol* i);
  745. static void WinControlFocus(win* p,wincontrol* Control,bool_t Set);
  746. static void WinControlSet(win* p,wincontrol* i,const datadef* DataDef,const void* Data,int Size,bool_t Update)
  747. {
  748. tchar_t DataOld[MAXDATA/sizeof(tchar_t)];
  749. if (i->Pin.Node->Get(i->Pin.Node,i->Pin.No,DataOld,Size)==ERR_NONE && memcmp(Data,DataOld,Size)==0)
  750. return;
  751. if (i->Pin.Node->Set(i->Pin.Node,i->Pin.No,Data,Size)==ERR_NONE)
  752. {
  753. p->Flags |= WIN_PROP_CHANGED;
  754. if (DataDef->Flags & DF_SOFTRESET)
  755. p->Flags |= WIN_PROP_SOFTRESET;
  756. if (DataDef->Flags & DF_RESTART)
  757. p->Flags |= WIN_PROP_RESTART;
  758. if (DataDef->Flags & DF_RESYNC)
  759. p->Flags |= WIN_PROP_RESYNC;
  760. if (Update)
  761. WinControlUpdate(p,i);
  762. }
  763. }
  764. static void WinControlCmd(win* p,wincontrol* i,HWND Control,int Cmd)
  765. {
  766. tchar_t s[256];
  767. datadef DataDef;
  768. switch (Cmd)
  769. {
  770. case CBN_CLOSEUP:
  771. if (i->ComboBox)
  772. p->ComboOpen = 0;
  773. break;
  774. case CBN_DROPDOWN:
  775. if (i->ComboBox)
  776. p->ComboOpen = 1;
  777. break;
  778. case LBN_SETFOCUS: //CBN_KILLFOCUS
  779. if (p->Smartphone)
  780. WinControlFocus(p,i,0);
  781. p->ComboOpen = 0;
  782. break;
  783. case EN_SETFOCUS:
  784. if (Control != i->Edit)
  785. DIASet(DIA_SIP,DIA_SIP);
  786. //no break
  787. case CBN_SETFOCUS:
  788. case BN_SETFOCUS:
  789. WinControlFocus(p,i,0);
  790. break;
  791. case EN_KILLFOCUS:
  792. if (Control != i->Edit)
  793. DIASet(0,DIA_SIP);
  794. break;
  795. case EN_CHANGE:
  796. if (!p->InUpdate && NodeDataDef(i->Pin.Node,i->Pin.No,&DataDef))
  797. {
  798. if (DataDef.Type == TYPE_STRING)
  799. {
  800. GetWindowText(Control,s,TSIZEOF(s));
  801. WinControlSet(p,i,&DataDef,s,sizeof(s),0);
  802. }
  803. else
  804. if (GetWindowText(Control,s,TSIZEOF(s))>0)
  805. {
  806. fraction f;
  807. tick_t t;
  808. int v = StringToInt(s,0);
  809. switch (DataDef.Type)
  810. {
  811. case TYPE_INT:
  812. if (DataDef.Flags & DF_PERCENT)
  813. v = ScaleRound(v,PERCENT_ONE,100);
  814. WinControlSet(p,i,&DataDef,&v,sizeof(v),0);
  815. break;
  816. case TYPE_TICK:
  817. if (DataDef.Flags & DF_MSEC)
  818. t = ScaleRound(v,TICKSPERSEC,1000);
  819. else
  820. t = v*TICKSPERSEC;
  821. WinControlSet(p,i,&DataDef,&t,sizeof(t),0);
  822. break;
  823. case TYPE_FRACTION:
  824. f.Num = v;
  825. f.Den = 100;
  826. WinControlSet(p,i,&DataDef,&f,sizeof(f),0);
  827. break;
  828. }
  829. }
  830. }
  831. break;
  832. case STN_CLICKED: //BN_CLICKED:
  833. case LBN_SELCHANGE: //STN_DBLCLK: CBN_SELCHANGE:
  834. if (i->Ref)
  835. WinControlFocus(p,i->Ref,1);
  836. else
  837. if (!p->InUpdate && NodeDataDef(i->Pin.Node,i->Pin.No,&DataDef))
  838. {
  839. if (DataDef.Type == TYPE_RESET)
  840. {
  841. int Zero = 0;
  842. wincontrol* j;
  843. for (j=p->Controls;j;j=j->Next)
  844. if (GetDataDefType(j)==TYPE_INT)
  845. WinControlSet(p,j,&DataDef,&Zero,sizeof(Zero),1);
  846. }
  847. else
  848. if (DataDef.Type == TYPE_BOOL)
  849. {
  850. bool_t Data;
  851. if (i->Pin.Node->Get(i->Pin.Node,i->Pin.No,&Data,sizeof(Data))==ERR_NONE)
  852. {
  853. Data = !Data;
  854. WinControlSet(p,i,&DataDef,&Data,sizeof(Data),1);
  855. }
  856. }
  857. else
  858. if (DataDef.Type == TYPE_INT)
  859. {
  860. int Data;
  861. if (p->Smartphone)
  862. {
  863. Data = SendMessage(Control,LB_GETCURSEL,0,0);
  864. if (Data>=0)
  865. Data = SendMessage(Control,LB_GETITEMDATA,Data,0);
  866. else
  867. Data=0;
  868. }
  869. else
  870. {
  871. Data = SendMessage(Control,CB_GETCURSEL,0,0);
  872. if (Data>=0)
  873. Data = SendMessage(Control,CB_GETITEMDATA,Data,0);
  874. else
  875. Data=0;
  876. }
  877. WinControlSet(p,i,&DataDef,&Data,sizeof(Data),0);
  878. }
  879. else
  880. if (DataDef.Type == TYPE_HOTKEY)
  881. {
  882. int Data;
  883. if (i->Pin.Node->Get(i->Pin.Node,i->Pin.No,&Data,sizeof(Data))==ERR_NONE)
  884. {
  885. if (!Data)
  886. {
  887. node* QueryKey = NodeCreate(QUERYKEY_ID);
  888. if (QueryKey)
  889. {
  890. int Key;
  891. int Key2;
  892. ((win*)QueryKey)->Popup((win*)QueryKey,p);
  893. QueryKey->Get(QueryKey,QUERYKEY_KEY,&Key,sizeof(Key));
  894. QueryKey->Get(QueryKey,QUERYKEY_KEY2,&Key2,sizeof(Key2));
  895. if (Key)
  896. {
  897. wincontrol* j; 
  898. int Data2;
  899. int KeyCode = Key & ~HOTKEY_KEEP;
  900. int Key2Code = Key2 & ~HOTKEY_KEEP;
  901. if (!Key2Code) Key2Code = KeyCode;
  902. for (j=p->Controls;j;j=j->Next)
  903. if (j!=i && NodeDataDef(j->Pin.Node,j->Pin.No,&DataDef) && DataDef.Type == TYPE_HOTKEY &&
  904. j->Pin.Node->Get(j->Pin.Node,j->Pin.No,&Data2,sizeof(Data2))==ERR_NONE &&
  905. ((Data2 & ~HOTKEY_KEEP) == KeyCode || (Data2 & ~HOTKEY_KEEP) == Key2Code))
  906. {
  907. Data2 = 0;
  908. WinControlSet(p,j,&DataDef,&Data2,sizeof(Data2),1);
  909. }
  910. if (WinEssentialKey(KeyCode) && p->Smartphone)
  911. Key &= ~HOTKEY_KEEP;
  912. Data = Key;
  913. WinControlSet(p,i,&DataDef,&Data,sizeof(Data),1);
  914. }
  915. NodeDelete(QueryKey);
  916. }
  917. }
  918. else
  919. {
  920. Data = 0;
  921. WinControlSet(p,i,&DataDef,&Data,sizeof(Data),1);
  922. }
  923. }
  924. }
  925. }
  926. break;
  927. }
  928. }
  929. static void WinControlUpdate(win* p,wincontrol* i)
  930. {
  931. datadef DataDef;
  932. tchar_t Data[MAXDATA/sizeof(tchar_t)];
  933. tchar_t s[256];
  934. int Value;
  935. int Result;
  936. if (!NodeDataDef(i->Pin.Node,i->Pin.No,&DataDef))
  937. return;
  938. p->InUpdate = 1;
  939. Result = i->Pin.Node->Get(i->Pin.Node,i->Pin.No,Data,DataDef.Size);
  940. WinControlDisable(p,i,Result!=ERR_NONE);
  941. if (Result != ERR_NONE && Result != ERR_NOT_SUPPORTED)
  942. memset(Data,0,sizeof(Data));
  943. switch (DataDef.Type)
  944. {
  945. case TYPE_HOTKEY:
  946. HotKeyToString(s,TSIZEOF(s),*(int*)Data);
  947. SetWindowText(i->Edit,s);
  948. SetWindowText(i->Control,LangStr(PLATFORM_ID,*(int*)Data ? PLATFORM_CLEAR:PLATFORM_ASSIGN));
  949. break;
  950. case TYPE_BOOL:
  951. SendMessage(i->Control,BM_SETCHECK,*(bool_t*)Data?BST_CHECKED:BST_UNCHECKED,0);
  952. break;
  953. case TYPE_INT:
  954. if (DataDef.Flags & (DF_ENUMCLASS|DF_ENUMSTRING))
  955. {
  956. int GetCount;
  957. int GetItemData;
  958. int SetCurSel;
  959. int No,Count;
  960. #if defined(TARGET_WINCE)
  961. if (p->Smartphone)
  962. {
  963. GetCount = LB_GETCOUNT;
  964. GetItemData = LB_GETITEMDATA;
  965. SetCurSel = LB_SETCURSEL;
  966. }
  967. else
  968. #endif
  969. {
  970. GetCount = CB_GETCOUNT;
  971. GetItemData = CB_GETITEMDATA;
  972. SetCurSel = CB_SETCURSEL;
  973. }
  974. Count = SendMessage(i->Control,GetCount,0,0);
  975. for (No=0;No<Count;++No)
  976. if (SendMessage(i->Control,GetItemData,No,0) == *(int*)Data)
  977. break;
  978. if (No==Count)
  979. No=-1;
  980. SendMessage(i->Control,SetCurSel,No,0);
  981. break;
  982. }
  983. else
  984. if (DataDef.Flags & DF_MINMAX)
  985. {
  986. if (DataDef.Type == TYPE_TICK)
  987. Value = *(tick_t*)Data;
  988. else
  989. Value = *(int*)Data;
  990. if (DataDef.Format2 - DataDef.Format1 <= TRACKMAX)
  991. Value -= DataDef.Format1;
  992. else
  993. Value = Scale(Value - DataDef.Format1,TRACKMAX,DataDef.Format2 - DataDef.Format1);
  994. SendMessage(i->Control,TBM_SETPOS,1,Value);
  995. break;
  996. }
  997. else
  998. {
  999. if (DataDef.Flags & DF_PERCENT)
  1000. {
  1001. if (*(int*)Data > 0)
  1002. IntToString(s,TSIZEOF(s),ScaleRound(*(int*)Data,100,PERCENT_ONE),0);
  1003. else
  1004. s[0]=0;
  1005. }
  1006. else
  1007. IntToString(s,TSIZEOF(s),*(int*)Data,0);
  1008. SetWindowText(i->Control,s);
  1009. SendMessage(i->Control,EM_SETSEL,tcslen(s),tcslen(s));
  1010. }
  1011. break;
  1012. case TYPE_STRING:
  1013. SetWindowText(i->Control,Data);
  1014. SendMessage(i->Control,EM_SETSEL,tcslen(s),tcslen(s));
  1015. break;
  1016. case TYPE_TICK:
  1017. if (DataDef.Flags & DF_MSEC)
  1018. stprintf_s(s,TSIZEOF(s),T("%d"),ScaleRound(*(tick_t*)Data,1000,TICKSPERSEC));
  1019. else
  1020. stprintf_s(s,TSIZEOF(s),T("%d"),ScaleRound(*(tick_t*)Data,1,TICKSPERSEC));
  1021. SetWindowText(i->Control,s);
  1022. SendMessage(i->Control,EM_SETSEL,tcslen(s),tcslen(s));
  1023. break;
  1024. case TYPE_FRACTION:
  1025. if (((fraction*)Data)->Num > 0)
  1026. stprintf_s(s,TSIZEOF(s),T("%d"),ScaleRound(((fraction*)Data)->Num,100,((fraction*)Data)->Den));
  1027. else
  1028. s[0] = 0;
  1029. SetWindowText(i->Control,s);
  1030. SendMessage(i->Control,EM_SETSEL,tcslen(s),tcslen(s));
  1031. break;
  1032. }
  1033. p->InUpdate = 0;
  1034. }
  1035. winunit WinPixelToUnitX(win* p,int Pixel) { return ScaleRound(Pixel,72,p->LogPixelSX); }
  1036. winunit WinPixelToUnitY(win* p,int Pixel) { return ScaleRound(Pixel,72,p->LogPixelSY); }
  1037. int WinUnitToPixelX(win* p,winunit Pos) { return ScaleRound(Pos,p->LogPixelSX,72); }
  1038. int WinUnitToPixelY(win* p,winunit Pos) { return ScaleRound(Pos,p->LogPixelSY,72); }
  1039. void WinProp( win* p, int* x0,int* x1)
  1040. {
  1041. *x0 = 2;
  1042. *x1 = p->LabelWidth + *x0;
  1043. if (*x1 > (p->Width*3)/4)
  1044. *x1 = (p->Width*3)/4;
  1045. *x1++;
  1046. }
  1047. static wincontrol* CreateControl(win* p,int Size)
  1048. {
  1049. wincontrol* Control = malloc(Size);
  1050. if (Control)
  1051. {
  1052. wincontrol** i;
  1053. memset(Control,0,Size);
  1054. for (i=&p->Controls;*i;i=&(*i)->Next);
  1055. *i = Control;
  1056. }
  1057. return Control;
  1058. }
  1059. static int CreateEnum(win* p, wincontrol* Control, int Left, int Top, int Width, int Height, const datadef* DataDef)
  1060. {
  1061. int No;
  1062. int Pos;
  1063. int AddString;
  1064. int ItemData;
  1065. int MaxWidth;
  1066. int FontSize;
  1067. int Plus = 0;
  1068. MaxWidth = WinUnitToPixelX(p,(DataDef->Flags & DF_ENUMSTRING) ? 80:180);
  1069. if (Width > MaxWidth)
  1070. Width = MaxWidth;
  1071. if (p->Smartphone)
  1072. {
  1073. Control->Control = CreateWindow(T("listbox"), NULL, WS_TABSTOP|WS_VISIBLE|WS_CHILD|LBS_NOTIFY|LBS_NOINTEGRALHEIGHT|((DataDef->Flags & DF_ENUMUNSORT)?0:LBS_SORT), 
  1074. Left, Top, Width, Height, p->WndDialog, NULL, p->Module, 0L);
  1075. Control->Edit = CreateWindow(UPDOWN_CLASS, NULL, WS_CHILD|WS_VISIBLE | UDS_HORZ |UDS_ALIGNRIGHT | UDS_ARROWKEYS |  UDS_SETBUDDYINT | UDS_WRAP | UDS_EXPANDABLE, 
  1076. 0, 0, 0, 0, p->WndDialog, NULL, p->Module, 0L);
  1077. SendMessage(Control->Edit, UDM_SETBUDDY, (WPARAM)Control->Control, 0);
  1078. AddString = LB_ADDSTRING;
  1079. ItemData = LB_SETITEMDATA;
  1080. FontSize = PROPSIZE;
  1081. SendMessage(Control->Edit,WM_SETFONT,(WPARAM)WinFont(p,&FontSize,1),0);
  1082. }
  1083. else
  1084. {
  1085. Control->Control = CreateWindow(T("COMBOBOX"), NULL, WS_VSCROLL|WS_TABSTOP|WS_VISIBLE|WS_CHILD|CBS_DROPDOWNLIST|((DataDef->Flags & DF_ENUMUNSORT)?0:CBS_SORT), 
  1086. Left, Top, Width, Height*(p->MenuSmall?10:15), p->WndDialog, NULL, p->Module, 0L);
  1087. Control->ComboBox = 1;
  1088. AddString = CB_ADDSTRING;
  1089. ItemData = CB_SETITEMDATA;
  1090. Plus = 6;
  1091. FontSize = PROPSIZE;
  1092. SendMessage(Control->Control,WM_SETFONT,(WPARAM)WinFont(p,&FontSize,1),0);
  1093. }
  1094. if (DataDef->Flags & DF_ENUMCLASS)
  1095. {
  1096. array List;
  1097. int *i;
  1098. NodeEnumClass(&List,DataDef->Format1);
  1099. for (i=ARRAYBEGIN(List,int);i!=ARRAYEND(List,int);++i)
  1100. {
  1101. Pos = SendMessage(Control->Control,AddString,0,(LPARAM)LangStr(*i,NODE_NAME));
  1102. SendMessage(Control->Control,ItemData,Pos,*i);
  1103. }
  1104. ArrayClear(&List);
  1105. }
  1106. else
  1107. if (DataDef->Flags & DF_ENUMSTRING)
  1108. {
  1109. int Id;
  1110. for (No=0;(Id=LangEnum(DataDef->Format1,No))!=0;++No)
  1111. {
  1112. Pos = SendMessage(Control->Control,AddString,0,(LPARAM)LangStr(DataDef->Format1,Id));
  1113. SendMessage(Control->Control,ItemData,Pos,Id);
  1114. }
  1115. }
  1116. return Plus;
  1117. }
  1118. static void CreateEditor(win* p, wincontrol* Control, int Left, int Top, int Width, int Height, const datadef* DataDef)
  1119. {
  1120. tchar_t Post[32];
  1121. int FontSize;
  1122. int Style = ES_NUMBER;
  1123. if (DataDef->Flags & DF_NEG)
  1124. Style = 0;
  1125. if (DataDef->Type==TYPE_STRING)
  1126. Style = ES_AUTOHSCROLL;
  1127. #ifdef TARGET_WIN32
  1128. if ((Width > 32) && DataDef->Type!=TYPE_STRING)
  1129. Width = 32;
  1130. #else
  1131. if ((Width > 30) && DataDef->Type!=TYPE_STRING)
  1132. Width = 30;
  1133. #endif
  1134. Control->Control = CreateWindow(T("EDIT"), NULL, WS_TABSTOP|WS_VISIBLE|WS_CHILD|Style, 
  1135. WinUnitToPixelX(p,Left), WinUnitToPixelY(p,Top), 
  1136. WinUnitToPixelX(p,Width), WinUnitToPixelY(p,Height), 
  1137. p->WndDialog, NULL, p->Module, 0L);
  1138. FontSize = PROPSIZE;
  1139. SendMessage(Control->Control,WM_SETFONT,(WPARAM)WinFont(p,&FontSize,1),0);
  1140. Control->Editor = 1;
  1141. Post[0] = 0;
  1142. if (DataDef->Flags & DF_KBYTE)
  1143. tcscpy_s(Post,TSIZEOF(Post),T("KB"));
  1144. else
  1145. if (DataDef->Flags & DF_MHZ)
  1146. tcscpy_s(Post,TSIZEOF(Post),T("Mhz"));
  1147. else
  1148. if (DataDef->Flags & DF_PERCENT)
  1149. tcscpy_s(Post,TSIZEOF(Post),T("%"));
  1150. else
  1151. if (DataDef->Type == TYPE_TICK)
  1152. tcscpy_s(Post,TSIZEOF(Post),(DataDef->Flags & DF_MSEC) ? T("msec"):T("sec"));
  1153. if (Post[0])
  1154. WinLabel(p,&Top,Left+Width+1,-1,Post,11,0,NULL);
  1155. }
  1156. wincontrol* WinPropNative(win* p, node* Node, int No)
  1157. {
  1158. wincontrol* Control = CreateControl(p,sizeof(wincontrol));
  1159. if (Control)
  1160. {
  1161. Control->Pin.Node = Node;
  1162. Control->Pin.No = No;
  1163. }
  1164. return Control;
  1165. }
  1166. wincontrol* WinPropValue(win* p, winunit* DlgTop, node* Node, int No)
  1167. {
  1168. int FontSize;
  1169. int Height,Width;
  1170. int Gap = WinUnitToPixelX(p,2);
  1171. int Top = WinUnitToPixelY(p,*DlgTop);
  1172. int Left;
  1173. winunit x,x0,x1,y1,y2;
  1174. wincontrol* Control;
  1175. datadef DataDef;
  1176. if (!NodeDataDef(Node,No,&DataDef))
  1177. return NULL;
  1178. Control = WinPropNative(p,Node,No);
  1179. if (!Control)
  1180. return NULL;
  1181. if (DataDef.Flags & DF_SHORTLABEL)
  1182. {
  1183. if (p->Smartphone)
  1184. x1 = 36;
  1185. else
  1186. x1 = 48;
  1187. x0 = 2;
  1188. Width = x1-x0-2; 
  1189. }
  1190. else
  1191. if ((DataDef.Flags & DF_CHECKLIST) && DataDef.Type==TYPE_BOOL)
  1192. {
  1193. x0 = 4+PROPSIZE;
  1194. x1 = 2;
  1195. Width = -1;
  1196. }
  1197. else
  1198. {
  1199. WinProp(p,&x0,&x1);
  1200. Width = x1-x0-2;
  1201. }
  1202. if (DataDef.Flags & DF_NOWRAP)
  1203. Width = -1;
  1204. y1 = *DlgTop;
  1205. if (DataDef.Type != TYPE_RESET)
  1206. WinLabel(p,&y1,x0,Width,DataDef.Name,PROPSIZE,0,Control);
  1207. else
  1208. x1 = x0;
  1209. y2 = *DlgTop + PROPSIZE+1;
  1210. Width = WinUnitToPixelX(p,PROPSIZE+1);
  1211. Height = WinUnitToPixelY(p,PROPSIZE+1);
  1212. Left = WinUnitToPixelX(p,x1);
  1213. switch (DataDef.Type)
  1214. {
  1215. case TYPE_RESET:
  1216. Control->Control = CreateWindow(T("BUTTON"),NULL,WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_NOTIFY,
  1217. Left+Gap,Top,Width*5,WinUnitToPixelY(p,PROPSIZE+2), p->WndDialog, NULL, p->Module, NULL);
  1218. y2 += 2;
  1219. FontSize = PROPSIZE;
  1220. SendMessage(Control->Control,WM_SETFONT,(WPARAM)WinFont(p,&FontSize,0),0);
  1221. SetWindowText(Control->Control,DataDef.Name);
  1222. break;
  1223. case TYPE_HOTKEY:
  1224. x = (Width*7)/2;
  1225. Control->Edit = CreateWindow(T("EDIT"),NULL,ES_READONLY|ES_AUTOHSCROLL|WS_VISIBLE|WS_CHILD,
  1226. Left,Top,x,Height, p->WndDialog, NULL, p->Module, NULL );
  1227. Control->Control = CreateWindow(T("BUTTON"),NULL,WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_NOTIFY,
  1228. Left+x+Gap,Top,(Width*5)/2,WinUnitToPixelY(p,PROPSIZE+2), p->WndDialog, NULL, p->Module, NULL);
  1229. FontSize = PROPSIZE;
  1230. SendMessage(Control->Edit,WM_SETFONT,(WPARAM)WinFont(p,&FontSize,1),0);
  1231. FontSize = PROPSIZE;
  1232. SendMessage(Control->Control,WM_SETFONT,(WPARAM)WinFont(p,&FontSize,0),0);
  1233. y2 += 2;
  1234. break;
  1235. case TYPE_BOOL:
  1236. Control->Control = CreateWindow(T("BUTTON"),NULL,WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_CHECKBOX|BS_NOTIFY,
  1237. Left,Top,Width,Height,p->WndDialog,NULL,p->Module,NULL);
  1238. break;
  1239. case TYPE_INT:
  1240. if (DataDef.Flags & (DF_ENUMCLASS|DF_ENUMSTRING))
  1241. {
  1242. y2 += CreateEnum(p,Control,Left,Top,WinUnitToPixelX(p,p->Width-x1),Height,&DataDef);
  1243. break;
  1244. }
  1245. else
  1246. if (DataDef.Flags & DF_MINMAX)
  1247. {
  1248. int Interval;
  1249. Width = p->Width-x1;
  1250. if (Width > 100)
  1251. Width = 100;
  1252. if (Width < 65 && !(DataDef.Flags & DF_NOWRAP))
  1253. {
  1254. y2 = y1 + PROPSIZE+1;
  1255. x1 = x0;
  1256. Width = p->Width-x1;
  1257. if (Width > 200)
  1258. Width = 200;
  1259. Left = WinUnitToPixelX(p,x1);
  1260. Top = WinUnitToPixelY(p,y1);
  1261. }
  1262. Control->Control = CreateWindowEx( 
  1263. 0,                    
  1264. TRACKBAR_CLASS,       
  1265. NULL,   
  1266. WS_TABSTOP|WS_CHILD | WS_VISIBLE | TBS_HORZ|TBS_BOTH|TBS_NOTICKS|TBS_FIXEDLENGTH, 
  1267. Left,Top,    
  1268. WinUnitToPixelX(p,Width), Height,   
  1269. p->WndDialog,
  1270. NULL,
  1271. p->Module,                     
  1272. NULL); 
  1273. Interval = DataDef.Format2 - DataDef.Format1;
  1274. if (Interval > TRACKMAX)
  1275. Interval = TRACKMAX;
  1276. SendMessage(Control->Control, TBM_SETRANGE, FALSE,MAKELONG(0,Interval));
  1277. SendMessage(Control->Control, TBM_SETPAGESIZE,0,Interval/32);
  1278. SendMessage(Control->Control, TBM_SETLINESIZE,0,Interval/32);
  1279. SendMessage(Control->Control, TBM_SETTHUMBLENGTH, WinUnitToPixelY(p,TRACKTHUMB),0);
  1280. break;
  1281. }
  1282. // no break
  1283. case TYPE_STRING:
  1284. case TYPE_TICK:
  1285. case TYPE_FRACTION:
  1286. CreateEditor(p,Control,x1,*DlgTop,p->Width-x1,PROPSIZE+1,&DataDef);
  1287. y2 += 1;
  1288. break;
  1289. }
  1290. SetWindowLong(Control->Control,GWL_USERDATA,(LONG)Control);
  1291. WinControlUpdate(p,Control);
  1292. *DlgTop = y1>y2?y1:y2;
  1293. return Control;
  1294. }
  1295. bool_t WinNoHotKey(int HotKey)
  1296. {
  1297. int Model = QueryPlatform(PLATFORM_MODEL);
  1298. if (Model == MODEL_TOSHIBA_E800) // record button mapping works on E800...
  1299. return 0;
  1300. HotKey &= ~HOTKEY_KEEP;
  1301. if (((HotKey & HOTKEY_MASK) == 0xC5 || HotKey == VK_ESCAPE || HotKey == VK_F1 || 
  1302.  HotKey == VK_F2 || HotKey == VK_F3 || HotKey == VK_F4 ||
  1303.  HotKey == VK_F6 || HotKey == VK_F7) && 
  1304. (QueryPlatform(PLATFORM_TYPENO) == TYPE_POCKETPC ||
  1305.  QueryPlatform(PLATFORM_TYPENO) == TYPE_SMARTPHONE))
  1306. return 1; // record, softkey1,2, talk, end, volume up/odwn
  1307. return 0;
  1308. }
  1309. bool_t WinEssentialKey(int HotKey)
  1310. {
  1311. HotKey &= ~HOTKEY_KEEP;
  1312. return 
  1313. HotKey == 0x86 || //action
  1314. HotKey == VK_RETURN ||
  1315. HotKey == VK_LEFT || // (need to be essential for D-pad rotation support too!)
  1316. HotKey == VK_RIGHT ||
  1317. HotKey == VK_UP ||
  1318. HotKey == VK_DOWN; // should use normal WM_KEYDOWN event for them
  1319. }
  1320. static void AddButton(win* p,int Pos,int Id,int Bitmap,tchar_t* Name,bool_t Check)
  1321. {
  1322. TBBUTTON Button;
  1323. memset(&Button,0,sizeof(Button));
  1324. Button.iBitmap = p->BitmapNo + Bitmap;
  1325. Button.idCommand = Id;
  1326. Button.fsState = TBSTATE_ENABLED;
  1327. Button.fsStyle = (BYTE)((Check ? TBSTYLE_CHECK : TBSTYLE_BUTTON) | TBSTYLE_AUTOSIZE | BTNS_SHOWTEXT);
  1328. Button.dwData = 0;
  1329. Button.iString = 0;
  1330. if (Id<0)
  1331. {
  1332. Button.idCommand = 0;
  1333. Button.fsStyle = TBSTYLE_SEP;
  1334. if (!p->AygShellTB && !(p->Flags & WIN_DIALOG) && GetSystemMetrics(SM_CXSCREEN)<=240)
  1335. return;
  1336. }
  1337. if (p->WndTB)
  1338. {
  1339. SendMessage(p->WndTB,TB_INSERTBUTTON,Pos,(LPARAM)&Button);
  1340. if (Name && Id>0)
  1341. {
  1342. TBBUTTONINFO Button;
  1343. Button.cbSize = sizeof(Button);
  1344. Button.dwMask = TBIF_TEXT;
  1345. Button.pszText = Name;
  1346. SendMessage(p->WndTB,TB_SETBUTTONINFO,Id,(LPARAM)&Button);
  1347. }
  1348. }
  1349. }
  1350. static int FindButton(win* p,int Id)
  1351. {
  1352. if (p->WndTB)
  1353. {
  1354. int i;
  1355. int n=SendMessage(p->WndTB,TB_BUTTONCOUNT,0,0);
  1356. for (i=0;i<n;++i)
  1357. {
  1358. TBBUTTON Button;
  1359. SendMessage(p->WndTB,TB_GETBUTTON,i,(LPARAM)&Button);
  1360. if (Button.idCommand == Id)
  1361. return i;
  1362. }
  1363. }
  1364. return -1;
  1365. }
  1366. void WinDeleteButton(win* p,int Id)
  1367. {
  1368. int No = FindButton(p,Id);
  1369. if (No>=0)
  1370. SendMessage(p->WndTB,TB_DELETEBUTTON,No,0);
  1371. }
  1372. void WinAddButton(win* p,int Id,int Bitmap,tchar_t* Name,bool_t Check)
  1373. {
  1374. if (p->WndTB)
  1375. AddButton(p,SendMessage(p->WndTB,TB_BUTTONCOUNT,0,0),Id,Bitmap,Name,Check);
  1376. }
  1377. win* WinGetObject(HWND Wnd)
  1378. {
  1379. return (win*) GetWindowLong(Wnd,GWL_USERDATA);
  1380. }
  1381. void WinSetObject(HWND Wnd,win* p)
  1382. {
  1383. SetWindowLong(Wnd,GWL_USERDATA,(LONG)p);
  1384. }
  1385. void WinRegisterHotKey(win* p,int Id,int HotKey)
  1386. {
  1387. #if defined(NDEBUG) || defined(TARGET_WINCE)
  1388. int Mod = MOD_KEYUP;
  1389. HotKey &= ~HOTKEY_KEEP;
  1390. //if (WinNoHotKey(HotKey)) return; //don't force, some devices support those hotkeys
  1391. if (HotKey & HOTKEY_ALT) Mod |= MOD_ALT;
  1392. if (HotKey & HOTKEY_SHIFT) Mod |= MOD_SHIFT;
  1393. if (HotKey & HOTKEY_CTRL) Mod |= MOD_CONTROL;
  1394. if (HotKey & HOTKEY_WIN) Mod |= MOD_WIN;
  1395. HotKey &= HOTKEY_MASK;
  1396. if (FuncUnregisterFunc1)
  1397. FuncUnregisterFunc1(Mod,HotKey);
  1398. RegisterHotKey(p->Wnd,Id,Mod,HotKey);
  1399. #endif
  1400. }
  1401. void WinUnRegisterHotKey(win* p,int Id)
  1402. {
  1403. #if defined(NDEBUG) || defined(TARGET_WINCE)
  1404. UnregisterHotKey(p->Wnd,Id);
  1405. #endif
  1406. }
  1407. wincontrol* WinPropLabel(win* p, winunit* Top, const tchar_t* LockedMsg, const tchar_t* Value)
  1408. {
  1409. wincontrol* Control;
  1410. int x0,x1;
  1411. int y2=*Top,y1=*Top;
  1412. WinProp(p,&x0,&x1);
  1413. Control = WinLabel(p,&y2,x1,-1,Value,PROPSIZE,LABEL_BOLD,NULL);
  1414. if (Control && !(p->Flags & WIN_NOTABSTOP))
  1415. Control->Disabled = 0; // tab stop
  1416. WinLabel(p,&y1,x0,x1-x0-2,LockedMsg,PROPSIZE,0,Control);
  1417. *Top = y1>y2 ? y1:y2;
  1418. return Control;
  1419. }
  1420. static void WinUpdateScroll(win* p);
  1421. static void WinNext(win* p,bool_t Prev);
  1422. int WinKeyState(int Key)
  1423. {
  1424. if (GetKeyState(VK_CONTROL)<0) Key |= HOTKEY_CTRL;
  1425. if (GetKeyState(VK_SHIFT)<0) Key |= HOTKEY_SHIFT;
  1426. if (GetKeyState(VK_MENU)<0) Key |= HOTKEY_ALT;
  1427. if (GetKeyState(VK_LWIN)<0 || GetKeyState(VK_RWIN)<0) Key |= HOTKEY_WIN;
  1428. //if (Key >= 0xC1 && Key <= 0xCF) Key |= HOTKEY_WIN; // h3800 ???
  1429. return Key;
  1430. }
  1431. void WinAllKeys(bool_t State)
  1432. {
  1433. if (FuncAllKeys)
  1434. FuncAllKeys(State);
  1435. }
  1436. void* WinCursorArrow()
  1437. {
  1438. #if defined(TARGET_WINCE)
  1439. return NULL;
  1440. #else
  1441. return LoadCursor(NULL,IDC_ARROW);
  1442. #endif
  1443. }
  1444. static void WinControlDelete(win* p,wincontrol* Control)
  1445. {
  1446. wincontrol** i;
  1447. for (i=&p->Controls;*i && *i!=Control;i=&(*i)->Next);
  1448. if (*i)
  1449. *i = Control->Next;
  1450. if (!Control->External)
  1451. {
  1452. if (Control->Control)
  1453. DestroyWindow(Control->Control);
  1454. if (Control->Edit)
  1455. DestroyWindow(Control->Edit);
  1456. }
  1457. free(Control);
  1458. }
  1459. static void WinClear( win* p)
  1460. {
  1461. p->Focus = NULL;
  1462. while (p->Controls)
  1463. WinControlDelete(p,p->Controls);
  1464. }
  1465. void WinBeginUpdate(win* p)
  1466. {
  1467. ShowWindow(p->WndDialog,SW_HIDE);
  1468. WinClear(p);
  1469. }
  1470. void WinEndUpdate(win* p)
  1471. {
  1472. if (!p->Focus)
  1473. WinNext(p,0);
  1474. ShowWindow(p->WndDialog,SW_SHOWNA);
  1475. WinUpdateScroll(p);
  1476. }
  1477. void WinMenuInsert(win* p,int No,int PrevId,int Id,const tchar_t* LockedMsg)
  1478. {
  1479. if (p->Menu2[No])
  1480. InsertMenu(p->Menu2[No],PrevId,MF_BYCOMMAND|MF_STRING,Id,LockedMsg);
  1481. }
  1482. bool_t WinMenuDelete(win* p,int No,int Id)
  1483. {
  1484. if (p->Menu2[No])
  1485. return DeleteMenu(p->Menu2[No],Id,MF_BYCOMMAND)!=0;
  1486. return 0;
  1487. }
  1488. bool_t WinMenuEnable(win* p,int No,int Id,bool_t State)
  1489. {
  1490. if (p->Menu2[No])
  1491. return EnableMenuItem(p->Menu2[No],Id,(State ? MF_ENABLED:MF_GRAYED)|MF_BYCOMMAND) != -1;
  1492. return 0;
  1493. }
  1494. int WinMenuFind(win* p,int Id)
  1495. {
  1496. int No;
  1497. MENUITEMINFO Info;
  1498. if (p->Menu3)
  1499. return 0;
  1500. Info.cbSize = sizeof(Info);
  1501. Info.fMask = 0;
  1502. for (No=0;No<2;++No)
  1503. {
  1504. if (p->Menu2[No] && GetMenuItemInfo(p->Menu2[No],Id,FALSE,&Info))
  1505. return No;
  1506. }
  1507. return 0;
  1508. }
  1509. bool_t WinMenuCheck(win* p,int No,int Id,bool_t State)
  1510. {
  1511. if (p->Menu2[No])
  1512. return CheckMenuItem(p->Menu2[No],Id,State?MF_CHECKED:MF_UNCHECKED) != -1;
  1513. return 0;
  1514. }
  1515. void WinTitle(win* p,const tchar_t* LockedMsg)
  1516. {
  1517. SetWindowText(p->Wnd,LockedMsg);
  1518. }
  1519. int WinClose(win* p)
  1520. {
  1521. PostMessage(p->Wnd,WM_CLOSE,0,0);
  1522. return ERR_NONE;
  1523. }
  1524. wincontrol* WinLabel(win* p,winunit* DlgTop,winunit DlgLeft,winunit DlgWidth,const tchar_t* Msg,int FontSize,int Flags,wincontrol* Ref)
  1525. {
  1526. tchar_t s[256];
  1527. wincontrol* Result = NULL;
  1528. SIZE Size;
  1529. HDC DC = GetDC(p->Wnd);
  1530. HFONT OldFont;
  1531. HFONT Font = (HFONT)WinFont(p,&FontSize,(Flags & LABEL_BOLD)!=0);
  1532. int Style = WS_VISIBLE | WS_CHILD;
  1533. int Left,Width;
  1534. int Extra = WinUnitToPixelX(p,2);
  1535. if (DlgLeft<0)
  1536. {
  1537. DlgLeft = 2;
  1538. DlgWidth = p->Width-4;
  1539. }
  1540. Left = WinUnitToPixelX(p,DlgLeft);
  1541. Width = DlgWidth>0 ? WinUnitToPixelX(p,DlgWidth) : -1;
  1542. if (Ref)
  1543. Style |= SS_NOTIFY;
  1544. if (Flags & LABEL_CENTER)
  1545. Style |= SS_CENTER;
  1546. else
  1547. Style |= SS_LEFTNOWORDWRAP;
  1548. OldFont = SelectObject(DC,Font);
  1549. if (Msg)
  1550. while (*Msg)
  1551. {
  1552. while (*Msg == 10)
  1553. {
  1554. ++Msg;
  1555. *DlgTop += FontSize/3; // smaller gaps
  1556. }
  1557. if (*Msg)
  1558. {
  1559. tchar_t* i;
  1560. wincontrol* Control = CreateControl(p,sizeof(wincontrol));
  1561. if (!Control)
  1562. break;
  1563. tcscpy_s(s,TSIZEOF(s),Msg);
  1564. i = tcschr(s,10);
  1565. if (i) *i = 0;
  1566. for (;;)
  1567. {
  1568. GetTextExtentPoint(DC,s,tcslen(s),&Size);
  1569. Size.cx += Extra;
  1570. if (!s[0] || !s[1] || Width<0 || Size.cx <= Width)
  1571. break;
  1572. i = tcsrchr(s,' ');
  1573. if (i)
  1574. *i = 0;
  1575. else
  1576. s[tcslen(s)-1] = 0;
  1577. }
  1578. Control->Disabled = 1; // no user input
  1579. Control->Ref = Ref;
  1580. Control->Control = CreateWindow(T("STATIC"),s,Style,Left,WinUnitToPixelY(p,*DlgTop),
  1581. Width>0 ? Width : Size.cx, WinUnitToPixelY(p,FontSize), p->WndDialog, NULL, p->Module, NULL );
  1582. SetWindowLong(Control->Control,GWL_USERDATA,(LONG)Control);
  1583. SendMessage(Control->Control,WM_SETFONT,(WPARAM)Font,0);
  1584. *DlgTop += FontSize;
  1585. Msg += tcslen(s);
  1586. while (*Msg == ' ') ++Msg;
  1587. if (*Msg == 10) ++Msg;
  1588. if (!Result)
  1589. Result = Control;
  1590. }
  1591. }
  1592. SelectObject(DC,OldFont);
  1593. ReleaseDC(p->Wnd,DC);
  1594. return Result;
  1595. }
  1596. void* WinFont(win* p,winunit* FontSize,bool_t Bold)
  1597. {
  1598. HFONT Font;
  1599. int Size = WinUnitToPixelY(p,*FontSize);
  1600. if (Size && Size < MAXFONTSIZE)
  1601. {
  1602. if (!FontCache[Size][Bold])
  1603. {
  1604. LOGFONT LogFont;
  1605. memset(&LogFont,0,sizeof(LogFont));
  1606. tcscpy_s(LogFont.lfFaceName,TSIZEOF(LogFont.lfFaceName),T("MS Sans Serif"));
  1607. LogFont.lfHeight = Size;
  1608. LogFont.lfWidth = 0;
  1609. switch (Context()->Lang)
  1610. {
  1611. case FOURCC('A','R','_','_'):
  1612. LogFont.lfCharSet = ARABIC_CHARSET;
  1613. break;
  1614. case FOURCC('C','H','T','_'):
  1615. LogFont.lfCharSet = CHINESEBIG5_CHARSET;
  1616. break;
  1617. case FOURCC('C','H','S','_'):
  1618. LogFont.lfCharSet = GB2312_CHARSET;
  1619. break;
  1620. case FOURCC('R','U','_','_'):
  1621. LogFont.lfCharSet = RUSSIAN_CHARSET;
  1622. break;
  1623. case FOURCC('J','A','_','_'):
  1624. LogFont.lfCharSet = SHIFTJIS_CHARSET;
  1625. break;
  1626. case FOURCC('T','R','_','_'):
  1627. LogFont.lfCharSet = TURKISH_CHARSET;
  1628. break;
  1629. case FOURCC('K','O','_','_'):
  1630. LogFont.lfCharSet = HANGEUL_CHARSET;
  1631. break;
  1632. default:
  1633. LogFont.lfCharSet = OEM_CHARSET;
  1634. }
  1635. if (Bold)
  1636. LogFont.lfWeight = FW_BOLD;
  1637. FontCache[Size][Bold] = CreateFontIndirect(&LogFont);
  1638. }
  1639. Font = FontCache[Size][Bold];
  1640. }
  1641. else
  1642. {
  1643. LOGFONT LogFont;
  1644. Font = (HFONT)GetStockObject(SYSTEM_FONT);
  1645. GetObject(Font,sizeof(LogFont),&LogFont);
  1646. *FontSize = WinPixelToUnitY(p,abs(LogFont.lfHeight));
  1647. }
  1648. return Font;
  1649. }
  1650. static void UpdateDPI(win* p)
  1651. {
  1652. HDC DC = GetDC(p->Wnd);
  1653. p->LogPixelSX = GetDeviceCaps(DC, LOGPIXELSY);
  1654. p->LogPixelSY = GetDeviceCaps(DC, LOGPIXELSX);
  1655. p->ScreenWidth = WinPixelToUnitY(p,GetDeviceCaps(DC,HORZRES));
  1656. p->MenuSmall = WinPixelToUnitY(p,GetDeviceCaps(DC,VERTRES)) < 210;
  1657. ReleaseDC(p->Wnd,DC);
  1658. }
  1659. static void VScroll(win* p,int Cmd,int Delta);
  1660. static void HScroll(win* p,int Cmd,int Delta);
  1661. static void UpdateDialogSize(win* p)
  1662. {
  1663. RECT r;
  1664. GetClientRect(p->WndDialog,&r);
  1665. if (!p->ScrollV)
  1666. r.right -= GetSystemMetrics(SM_CXVSCROLL);
  1667. if (!p->ScrollH)
  1668. r.bottom -= GetSystemMetrics(SM_CYHSCROLL);
  1669. p->Width = WinPixelToUnitX(p,r.right);
  1670. p->Height = WinPixelToUnitY(p,r.bottom);
  1671. }
  1672. static void WinControlFocus(win* p,wincontrol* Control,bool_t Set)
  1673. {
  1674. wincontrol* i;
  1675. if (p->Focus == Control)
  1676. return;
  1677. if (Control && Control->Disabled)
  1678. return;
  1679. if (p->Focus)
  1680. for (i=p->Controls;i;i=i->Next)
  1681. if (i->Ref == p->Focus)
  1682. InvalidateRect(i->Control,NULL,TRUE);
  1683. p->Focus = Control;
  1684. if (Control)
  1685. {
  1686. POINT o;
  1687. RECT r;
  1688. int Min=MAX_INT;
  1689. int Max=-MAX_INT;
  1690. if (Control->Control && GetParent(Control->Control)==p->WndDialog)
  1691. {
  1692. GetWindowRect(Control->Control,&r);
  1693. if (r.bottom > Max)
  1694. Max = r.bottom;
  1695. if (r.top < Min)
  1696. Min = r.top;
  1697. }
  1698. for (i=p->Controls;i;i=i->Next)
  1699. if (i->Ref == Control)
  1700. {
  1701. GetWindowRect(i->Control,&r);
  1702. if (r.bottom > Max)
  1703. Max = r.bottom;
  1704. if (r.top < Min)
  1705. Min = r.top;
  1706. InvalidateRect(i->Control,NULL,TRUE);
  1707. }
  1708. if (Max > Min)
  1709. {
  1710. o.x = o.y = 0;
  1711. ClientToScreen(p->WndDialog,&o);
  1712. GetClientRect(p->WndDialog,&r);
  1713. r.top += o.y;
  1714. r.bottom += o.y;
  1715. if (r.top > Min)
  1716. VScroll(p,0,Max-r.bottom);
  1717. else
  1718. if (r.bottom < Max)
  1719. VScroll(p,0,Min-r.top);
  1720. }
  1721. if (Set)
  1722. if (Control->Control)
  1723. SetFocus(Control->Control);
  1724. else
  1725. SetFocus(p->WndDialog);
  1726. }
  1727. else
  1728. if (Set)
  1729. SetFocus(p->WndDialog);
  1730. }
  1731. static void WinNext(win* p,bool_t Prev)
  1732. {
  1733. wincontrol* Start = p->Focus;
  1734. wincontrol* Last;
  1735. wincontrol* i;
  1736. if (!Start)
  1737. {
  1738. Start = p->Controls;
  1739. if (!Start)
  1740. return;
  1741. if (!Start->Disabled)
  1742. {
  1743. WinControlFocus(p,Start,1);
  1744. return;
  1745. }
  1746. }
  1747. Last = Start;
  1748. do
  1749. {
  1750. if (Prev)
  1751. {
  1752. for (i=p->Controls;i->Next && i->Next!=Last;i=i->Next);
  1753. }
  1754. else
  1755. {
  1756. i = Last->Next;
  1757. if (!i) 
  1758. i=p->Controls;
  1759. }
  1760. Last = i;
  1761. }
  1762. while (i && i!=Start && i->Disabled);
  1763. WinControlFocus(p,i,1);
  1764. }
  1765. void WinPropFocus(win* p, node* Node, int No, bool_t SetFocus)
  1766. {
  1767. wincontrol* Control;
  1768. for (Control=p->Controls;Control;Control=Control->Next)
  1769. if (Control->Pin.Node == Node && Control->Pin.No == No)
  1770. {
  1771. WinControlFocus(p,Control,SetFocus);
  1772. break;
  1773. }
  1774. }
  1775. void WinPropUpdate(win* p, node* Node, int No)
  1776. {
  1777. wincontrol* Control;
  1778. for (Control=p->Controls;Control;Control=Control->Next)
  1779. if (Control->Pin.Node == Node && Control->Pin.No == No)
  1780. WinControlUpdate(p,Control);
  1781. }
  1782. static LRESULT CALLBACK DialogProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  1783. {
  1784. wincontrol* i;
  1785. int Result;
  1786. win* p = (win*)GetWindowLong(Wnd,GWL_USERDATA);
  1787. if (p && p->DialogProc && p->DialogProc(p,Msg,wParam,lParam,&Result))
  1788. return Result;
  1789. switch (Msg)
  1790. {
  1791. case WM_CREATE:
  1792. p = (win*)((CREATESTRUCT*)lParam)->lpCreateParams;
  1793. p->WndDialog = Wnd;
  1794. p->Controls = NULL;
  1795. p->Focus = NULL;
  1796. SetWindowLong(Wnd,GWL_USERDATA,(LONG)p);
  1797. break;
  1798. case WM_COMMAND:
  1799. i = (wincontrol*) GetWindowLong((HWND)lParam,GWL_USERDATA);
  1800. if (VALIDCONTROL(i))
  1801. WinControlCmd(p,i,(HWND)lParam,HIWORD(wParam));
  1802. break;
  1803. case WM_SIZE:
  1804. if (p)
  1805. UpdateDialogSize(p);
  1806. break;
  1807. case WM_SETFOCUS:
  1808. if (p->Focus && p->Focus->Control)
  1809. SetFocus(p->Focus->Control);
  1810. break;
  1811. case WM_DESTROY:
  1812. p->WndDialog = NULL;
  1813. break;
  1814. case WM_HSCROLL:
  1815. if (!lParam || !(GetWindowLong((HWND)lParam,GWL_STYLE) & (TBS_BOTH|TBS_NOTICKS|TBS_FIXEDLENGTH)))
  1816. HScroll(p,LOWORD(wParam),0);
  1817. else
  1818. {
  1819. i = (wincontrol*) GetWindowLong((HWND)lParam,GWL_USERDATA);
  1820. if (VALIDCONTROL(i))
  1821. {
  1822. WinControlFocus(p,i,1);
  1823. SetTrack(p,i,SendMessage((HWND)lParam,TBM_GETPOS,0,0));
  1824. }
  1825. }
  1826. break;
  1827. case WM_VSCROLL:
  1828. if (!lParam || !(GetWindowLong((HWND)lParam,GWL_STYLE) & (TBS_BOTH|TBS_NOTICKS|TBS_FIXEDLENGTH)))
  1829. VScroll(p,LOWORD(wParam),0);
  1830. break;
  1831. case WM_KEYDOWN:
  1832. if (wParam == VK_ESCAPE)
  1833. WinClose(p);
  1834. if (p->ScrollV && wParam == VK_UP)
  1835. VScroll(p,SB_LINEUP,0);
  1836. if (p->ScrollV && wParam == VK_DOWN)
  1837. VScroll(p,SB_LINEDOWN,0);
  1838. if (p->ScrollH && wParam == VK_LEFT)
  1839. HScroll(p,SB_LINEUP,0);
  1840. if (p->ScrollH && wParam == VK_RIGHT)
  1841. HScroll(p,SB_LINEDOWN,0);
  1842. break;
  1843. #if defined(TARGET_WINCE)
  1844. case WM_CTLCOLOREDIT:
  1845. SetBkColor((HDC)wParam,GetSysColor(COLOR_BTNFACE));
  1846. return (LRESULT) GetSysColorBrush(COLOR_BTNFACE);
  1847. #endif
  1848. case WM_CTLCOLORSTATIC:
  1849. i = (wincontrol*)GetWindowLong((HWND)lParam,GWL_USERDATA);
  1850. if (i && p->Focus && p->Focus == i->Ref)
  1851. {
  1852. if (p->Smartphone)
  1853. {
  1854. SetTextColor((HDC)wParam,GetSysColor(COLOR_HIGHLIGHTTEXT));
  1855. SetBkColor((HDC)wParam,GetSysColor(COLOR_HIGHLIGHT));
  1856. return (LRESULT) GetSysColorBrush(COLOR_HIGHLIGHT);
  1857. }
  1858. SetTextColor((HDC)wParam,0xC00000);
  1859. }
  1860. SetBkColor((HDC)wParam,GetSysColor(DIALOG_COLOR));
  1861. return (LRESULT) GetSysColorBrush(DIALOG_COLOR);
  1862. }
  1863. return DefWindowProc(Wnd,Msg,wParam,lParam);
  1864. }
  1865. static void WinScroll(win* p,int dx,int dy)
  1866. {
  1867. ScrollWindowEx(p->WndDialog, dx, dy, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN | SW_ERASE | SW_INVALIDATE );
  1868. }
  1869. static void WinUpdateScroll(win* p)
  1870. {
  1871. SCROLLINFO Scroll;
  1872. POINT Offset;
  1873. RECT Page;
  1874. int MaxWidth,MinWidth;
  1875. int MaxHeight,MinHeight;
  1876. HWND Child;
  1877. int XVScroll = GetSystemMetrics(SM_CXVSCROLL);
  1878. int YHScroll = GetSystemMetrics(SM_CYHSCROLL);
  1879. if (p->InUpdateScroll || p->OwnDialogSize)
  1880. return;
  1881. p->InUpdateScroll = 1;
  1882. Offset.x = Offset.y = 0;
  1883. ClientToScreen(p->WndDialog,&Offset);
  1884. GetClientRect(p->WndDialog,&Page);
  1885. if (p->ScrollV)
  1886. Page.right += XVScroll;
  1887. if (p->ScrollH)
  1888. Page.bottom += YHScroll;
  1889. MinWidth = 0;
  1890. MinHeight = 0;
  1891. MaxWidth = 0;
  1892. MaxHeight = 0;
  1893. Child = GetWindow(p->WndDialog,GW_CHILD);
  1894. while (Child && IsWindow(Child))
  1895. {
  1896. RECT r;
  1897. GetWindowRect(Child,&r);
  1898. r.left -= Offset.x;
  1899. r.right -= Offset.x; 
  1900. r.top -= Offset.y;
  1901. r.bottom -= Offset.y; 
  1902. r.bottom += YHScroll;
  1903. if (r.left < MinWidth) MinWidth = r.left;
  1904. if (r.right > MaxWidth) MaxWidth = r.right;
  1905. if (r.top < MinHeight) MinHeight = r.top;
  1906. if (r.bottom > MaxHeight) MaxHeight = r.bottom;
  1907. Child = GetWindow(Child,GW_HWNDNEXT);
  1908. }
  1909. Scroll.cbSize = sizeof(Scroll);
  1910. Scroll.fMask =  SIF_PAGE | SIF_RANGE | SIF_POS;
  1911. if (MaxHeight < Page.bottom)
  1912. MaxHeight = Page.bottom-1;
  1913. p->ScrollV = MaxHeight-MinHeight > Page.bottom;
  1914. Scroll.nMin = MinHeight;
  1915. Scroll.nMax = MaxHeight;
  1916. Scroll.nPos = 0;
  1917. Scroll.nPage = Page.bottom;
  1918. SetScrollInfo(p->WndDialog,SB_VERT,&Scroll,TRUE);
  1919. if (p->ScrollV)
  1920. Page.right -= XVScroll;
  1921. if (MaxWidth < Page.right)
  1922. MaxWidth = Page.right-1;
  1923. p->ScrollH = MaxWidth-MinWidth > Page.right;
  1924. Scroll.nMin = MinWidth;
  1925. Scroll.nMax = MaxWidth;
  1926. Scroll.nPos = 0;
  1927. Scroll.nPage = Page.right;
  1928. SetScrollInfo(p->WndDialog,SB_HORZ,&Scroll,TRUE);
  1929. p->InUpdateScroll = 0;
  1930. }
  1931. static void VScroll(win* p,int Cmd,int Delta)
  1932. {
  1933. int Pos;
  1934. SCROLLINFO Scroll;
  1935. Scroll.cbSize = sizeof(Scroll);
  1936. Scroll.fMask  = SIF_ALL;
  1937. GetScrollInfo(p->WndDialog, SB_VERT, &Scroll);
  1938. Pos = Scroll.nPos;
  1939. if (Delta)
  1940. Scroll.nPos += Delta;
  1941. else
  1942. switch (Cmd)
  1943. {
  1944. case SB_TOP:
  1945. Scroll.nPos = Scroll.nMin;
  1946. break;
  1947. case SB_BOTTOM:
  1948. Scroll.nPos = Scroll.nMax;
  1949. break;
  1950. case SB_LINEUP:
  1951. Scroll.nPos -= WinUnitToPixelY(p,16);
  1952. break;
  1953. case SB_LINEDOWN:
  1954. Scroll.nPos += WinUnitToPixelY(p,16);
  1955. break;
  1956. case SB_PAGEUP:
  1957. Scroll.nPos -= Scroll.nPage;
  1958. break;
  1959. case SB_PAGEDOWN:
  1960. Scroll.nPos += Scroll.nPage;
  1961. break;
  1962. case SB_THUMBTRACK:
  1963. Scroll.nPos = Scroll.nTrackPos;
  1964. break;
  1965. default:
  1966. break;
  1967. }
  1968. Scroll.fMask = SIF_POS;
  1969. SetScrollInfo(p->WndDialog, SB_VERT, &Scroll, TRUE);
  1970. GetScrollInfo(p->WndDialog, SB_VERT, &Scroll);
  1971. if (Scroll.nPos != Pos)
  1972. WinScroll(p,0,Pos - Scroll.nPos);
  1973. }
  1974. static void HScroll(win* p,int Cmd,int Delta)
  1975. {
  1976. int Pos;
  1977. SCROLLINFO Scroll;
  1978. Scroll.cbSize = sizeof(Scroll);
  1979. Scroll.fMask  = SIF_ALL;
  1980. GetScrollInfo(p->WndDialog, SB_HORZ, &Scroll);
  1981. Pos = Scroll.nPos;
  1982. if (Delta)
  1983. Scroll.nPos += Delta;
  1984. else
  1985. switch (Cmd)
  1986. {
  1987. case SB_TOP:
  1988. Scroll.nPos = Scroll.nMin;
  1989. break;
  1990. case SB_BOTTOM:
  1991. Scroll.nPos = Scroll.nMax;
  1992. break;
  1993. case SB_LINEUP:
  1994. Scroll.nPos -= WinUnitToPixelX(p,16);
  1995. break;
  1996. case SB_LINEDOWN:
  1997. Scroll.nPos += WinUnitToPixelX(p,16);
  1998. break;
  1999. case SB_PAGEUP:
  2000. Scroll.nPos -= Scroll.nPage;
  2001. break;
  2002. case SB_PAGEDOWN:
  2003. Scroll.nPos += Scroll.nPage;
  2004. break;
  2005. case SB_THUMBTRACK:
  2006. Scroll.nPos = Scroll.nTrackPos;
  2007. break;
  2008. default:
  2009. break;
  2010. }
  2011. Scroll.fMask = SIF_POS;
  2012. SetScrollInfo(p->WndDialog, SB_HORZ, &Scroll, TRUE);
  2013. GetScrollInfo(p->WndDialog, SB_HORZ, &Scroll);
  2014. if (Scroll.nPos != Pos)
  2015. WinScroll(p,Pos - Scroll.nPos,0);
  2016. }
  2017. static bool_t OwnWindow(HWND Wnd)
  2018. {
  2019. tchar_t ClassName[64];
  2020. for (;Wnd;Wnd=GetParent(Wnd))
  2021. {
  2022. GetClassName(Wnd,ClassName,64);
  2023. if (tcscmp(ClassName,WinClass.lpszClassName)==0 || 
  2024. tcscmp(ClassName,T("VolumeBack"))==0)
  2025. return 1;
  2026. }
  2027. return 0;
  2028. }
  2029. void ForwardMenuButtons(win* p,int Msg,uint32_t wParam,uint32_t lParam)
  2030. {
  2031. #if defined(TARGET_WINCE)
  2032. if (p->WndTB && (wParam == VK_F1 || wParam == VK_F2) &&
  2033. (QueryPlatform(PLATFORM_TYPENO) == TYPE_POCKETPC || 
  2034.  QueryPlatform(PLATFORM_TYPENO) == TYPE_SMARTPHONE))
  2035. {
  2036. if (Msg == WM_KEYDOWN && !(lParam & (1<<30)))
  2037. {
  2038. PostMessage(p->WndTB,WM_HOTKEY,0,MAKELPARAM(0,wParam));
  2039. PostMessage(p->WndTB,WM_HOTKEY,0,MAKELPARAM(0x1000,wParam));
  2040. }
  2041. }
  2042. #endif
  2043. }
  2044. static LRESULT CALLBACK Proc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  2045. {
  2046. int Result = 0;
  2047. win* p = (win*)GetWindowLong(Wnd,GWL_USERDATA);
  2048. switch (Msg)
  2049. {
  2050. #if defined(TARGET_WINCE)
  2051. case WM_HOTKEY:
  2052. if (p->Parent && HIWORD(lParam)==VK_ESCAPE)
  2053. {
  2054. HWND Focus = GetFocus();
  2055. wincontrol* i = (wincontrol*)GetWindowLong(Focus,GWL_USERDATA);
  2056. if (FuncSHSendBackToFocusWindow && ((VALIDCONTROL(i) && i->Editor) || (!VALIDCONTROL(i) && i)))
  2057. FuncSHSendBackToFocusWindow(Msg,wParam,lParam);
  2058. else
  2059. {
  2060. p->HotKeyEscape = !p->HotKeyEscape;
  2061. if (!p->HotKeyEscape)
  2062. PostMessage(p->Wnd,WM_CLOSE,0,0);
  2063. }
  2064. return 0;
  2065. }
  2066. break;
  2067. #endif
  2068. case WM_CREATE:
  2069. p = (win*)((CREATESTRUCT*)lParam)->lpCreateParams;
  2070. p->Wnd = Wnd;
  2071. p->Module = ((CREATESTRUCT*)lParam)->hInstance;
  2072. p->Result = 1;
  2073. p->Focus = NULL;
  2074. p->Closed = 0;
  2075. UpdateDPI(p);
  2076. #if defined(TARGET_WINCE)
  2077. p->Activate = malloc(sizeof(SHACTIVATEINFO));
  2078. if (p->Activate)
  2079. {
  2080. memset(p->Activate,0,sizeof(SHACTIVATEINFO));
  2081. ((SHACTIVATEINFO*)p->Activate)->cbSize = sizeof(SHACTIVATEINFO);
  2082. }
  2083. #endif
  2084. if (p->Proc)
  2085. p->Proc(p,MSG_PREPARE,0,0,&Result);
  2086. CreateToolBar(p);
  2087. SetWindowLong(Wnd,GWL_USERDATA,(LONG)p); // only after CreateToolBar (WM_MOVE)
  2088. if (p->Flags & WIN_DIALOG)
  2089. {
  2090. RECT r;
  2091. GetClientRect(p->Wnd,&r);
  2092. CreateWindow(DialogClass.lpszClassName,NULL,WS_CLIPCHILDREN|WS_CHILD|WS_VISIBLE,
  2093. 0,p->ToolBarHeight,r.right,r.bottom-p->ToolBarHeight,p->Wnd,NULL,DialogClass.hInstance,p);
  2094. }
  2095. if (p->Init)
  2096. p->Init(p);
  2097. if (!p->Focus)
  2098. WinNext(p,0);
  2099. break;
  2100. case WM_CLOSE:
  2101. p->Closed = 1;
  2102. p->Focus = NULL;
  2103. SetFocus(NULL);
  2104. if (p->Done)
  2105. p->Done(p);
  2106. if (p->WndDialog)
  2107. ShowWindow(p->WndDialog,SW_HIDE);
  2108. WinClear(p);
  2109. if (p->Parent)
  2110. {
  2111. EnableWindow(p->Parent->Wnd,TRUE);
  2112. p->Parent->Child = NULL;
  2113. SetForegroundWindow(p->Parent->Wnd);
  2114. DestroyWindow(p->Wnd);
  2115. }
  2116. break;
  2117. case WM_SETFOCUS:
  2118. if (p->WndDialog)
  2119. SetFocus(p->WndDialog);
  2120. if (!p->Parent)
  2121. WidcommAudio_Wnd(p->Wnd);
  2122. break;
  2123. case WM_SIZE:
  2124. if (p)
  2125. {
  2126. RECT r;
  2127. GetClientRect(p->Wnd,&r);
  2128. if (p->ToolBarHeight)
  2129. MoveWindow(p->WndTB,0,0,r.right,p->ToolBarHeight,TRUE);
  2130. if (p->WndDialog && !p->OwnDialogSize)
  2131. MoveWindow(p->WndDialog,0,p->ToolBarHeight,r.right,r.bottom-p->ToolBarHeight,TRUE);
  2132. }
  2133. break;
  2134. case WM_DESTROY:
  2135. WinSetFullScreen(p,0);
  2136. DestroyToolBar(p);
  2137. if (p->Menu3)
  2138. DestroyMenu(p->Menu3);
  2139. p->Wnd = NULL;
  2140. p->WndTB = NULL;
  2141. memset(p->Menu2,0,sizeof(p->Menu2));
  2142. break;
  2143. case WM_COMMAND:
  2144. if (LOWORD(wParam) == WIN_A)
  2145. wParam = p->WinCmd[0];
  2146. if (LOWORD(wParam) == WIN_B)
  2147. wParam = p->WinCmd[1];
  2148. if (LOWORD(wParam) == IDOK)
  2149. wParam = PLATFORM_OK;
  2150. if (p->Command && p->Command(p,LOWORD(wParam))==ERR_NONE)
  2151. return 0;
  2152. if (LOWORD(wParam) == PLATFORM_OK ||
  2153. LOWORD(wParam) == PLATFORM_DONE ||
  2154. LOWORD(wParam) == PLATFORM_CANCEL)
  2155. {
  2156. WinClose(p);
  2157. return 0;
  2158. }
  2159. break;
  2160. case WM_ACTIVATE:
  2161. if (LOWORD(wParam)!=WA_INACTIVE)
  2162. {
  2163. if (WidcommAudio_SkipActivate())
  2164. return 0;
  2165. if (!p->Parent)
  2166. WidcommAudio_Wnd(p->Wnd);
  2167. if (p->Child)
  2168. {
  2169. SetForegroundWindow(p->Child->Wnd);
  2170. return 0;
  2171. }
  2172. }
  2173. #if defined(TARGET_WINCE)
  2174. if (FuncSHHandleWMActivate && p->Activate && !TaskBarHidden)
  2175. FuncSHHandleWMActivate(Wnd, wParam, lParam, p->Activate, FALSE);
  2176. #endif
  2177. break;
  2178. case WM_SETTINGCHANGE:
  2179. #if defined(TARGET_WINCE) 
  2180. if (FuncSHHandleWMSettingChange && p->Activate && !TaskBarHidden)
  2181. FuncSHHandleWMSettingChange(Wnd, wParam, lParam, p->Activate);
  2182. #endif
  2183. UpdateDPI(p);
  2184. break;
  2185. }
  2186. if (p)
  2187. {
  2188. if (p->Proc && p->Proc(p,Msg,wParam,lParam,&Result))
  2189. return Result;
  2190. if (Msg == WM_ACTIVATE && !OwnWindow((HWND)lParam))
  2191. {
  2192. if (LOWORD(wParam)==WA_INACTIVE)
  2193. {
  2194. bool_t b = 1;
  2195. node* Player = Context()->Player;
  2196. if (Player && Main && !Main->Closed)
  2197. Player->Set(Player,PLAYER_BACKGROUND,&b,sizeof(b));
  2198. #if defined(TARGET_WINCE)
  2199. if (TaskBarHidden)
  2200. {
  2201. DIASet(DIA_TASKBAR,DIA_TASKBAR);
  2202. TaskBarHidden = 1;
  2203. }
  2204. #endif
  2205. }
  2206. else
  2207. {
  2208. bool_t b = 0;
  2209. node* Player = Context()->Player;
  2210. if (Player && Main && !Main->Closed)
  2211. Player->Set(Player,PLAYER_BACKGROUND,&b,sizeof(b));
  2212. #if defined(TARGET_WINCE)
  2213. if (TaskBarHidden)
  2214. {
  2215. TaskBarHidden = 0;
  2216. DIASet(0,DIA_TASKBAR);
  2217. }
  2218. #endif
  2219. }
  2220. }
  2221. #if defined(TARGET_WINCE)
  2222. if (Msg == WM_CREATE && !p->AygShellTB && ((p->Flags & WIN_DIALOG) || GetSystemMetrics(SM_CXSCREEN)>240))
  2223. CommandBar_AddAdornments(p->WndTB,p->NeedOK ? CMDBAR_OK:0,0);
  2224. #endif
  2225. if (p->WndDialog && (Msg == WM_CREATE || Msg == WM_SIZE))
  2226. WinUpdateScroll(p);
  2227. }
  2228. return DefWindowProc(Wnd,Msg,wParam,lParam);
  2229. }
  2230. static void HandleMessage(win* p,MSG* Msg)
  2231. {
  2232. int Result;
  2233. #if defined(TARGET_WINCE)
  2234. if (Msg->message == WM_HIBERNATE)
  2235. {
  2236. if (AvailMemory() < 256*1024) // don't mess up format_base buffering...
  2237. NodeHibernate();
  2238. }
  2239. #endif
  2240. if (Msg->message >= WM_APP + 0x200 && 
  2241. Msg->message <= WM_APP + 0x220)
  2242. {
  2243. // send to application window
  2244. win* Appl=p;
  2245. while (Appl->Parent)
  2246. Appl=Appl->Parent;
  2247. if (Appl->Proc(Appl,Msg->message,Msg->wParam,Msg->lParam,&Result))
  2248. return;
  2249. }
  2250. if (Msg->message == WM_KEYDOWN)
  2251. {
  2252. if (p->CaptureKeys && p->Proc && p->Proc(p,Msg->message,Msg->wParam,Msg->lParam,&Result))
  2253. return;
  2254. if (p->Focus)
  2255. {
  2256. int Type;
  2257. switch (Msg->wParam)
  2258. {
  2259. case VK_LEFT:
  2260. case VK_RIGHT:
  2261. if (!p->Focus->ListView)
  2262. {
  2263. Type = GetDataDefType(p->Focus);
  2264. if (!Type || Type == TYPE_BOOL || Type == TYPE_RESET || Type == TYPE_HOTKEY)
  2265. {
  2266. SendMessage(p->WndDialog,Msg->message,Msg->wParam,Msg->lParam);
  2267. return;
  2268. }
  2269. }
  2270. break;
  2271. case VK_RETURN:
  2272. Type = GetDataDefType(p->Focus);
  2273. if (Type == TYPE_BOOL || Type == TYPE_RESET || Type == TYPE_HOTKEY)
  2274. {
  2275. SendMessage(p->Focus->Control,BM_CLICK,0,0);
  2276. return;
  2277. }
  2278. if (p->Focus->ComboBox && !p->ComboOpen)
  2279. {
  2280. SendMessage(p->Focus->Control,CB_SHOWDROPDOWN,1,0);
  2281. return;
  2282. }
  2283. if (Type == TYPE_STRING)
  2284. {
  2285. SendMessage(p->WndDialog,Msg->message,Msg->wParam,Msg->lParam);
  2286. return;
  2287. }
  2288. break;
  2289. case VK_DOWN:
  2290. case VK_UP:
  2291. if (!p->ComboOpen && !p->Focus->ListView)
  2292. {
  2293. WinNext(p,Msg->wParam==VK_UP);
  2294. return;
  2295. }
  2296. break;
  2297. case VK_TAB:
  2298. WinNext(p,GetKeyState(VK_SHIFT)<0);
  2299. return;
  2300. }
  2301. }
  2302. }
  2303. TranslateMessage(Msg);
  2304. DispatchMessage(Msg);
  2305. }
  2306. int WinPopupClass(int Class,win* Parent)
  2307. {
  2308. int Result = 0;
  2309. node* p = NodeCreate(Class);
  2310. if (p && NodeIsClass(p->Class,WIN_CLASS))
  2311. {
  2312. Result = ((win*)p)->Popup((win*)p,Parent);
  2313. NodeDelete(p);
  2314. }
  2315. return Result;
  2316. }
  2317. static int Popup(win* p,win* Parent)
  2318. {
  2319. HWND Wnd;
  2320. MSG Msg;
  2321. int Style = WS_VISIBLE;
  2322. int ExStyle = 0;
  2323. int x,y;
  2324. int Width,Height;
  2325. int Priority;
  2326. // we need higher priority in main window for better user interface responses
  2327. // but open dialog and other parts can't have that, because of some buggy keyboard drivers...
  2328. Priority = ThreadPriority(NULL,Parent?0:-1);
  2329. p->Result = 0;
  2330. p->Parent = Parent;
  2331. p->BitmapNo = 0;
  2332. p->AygShellTB = 0;
  2333. #if defined(TARGET_WINCE)
  2334. if (AygShell && Parent)
  2335. ExStyle |= WS_EX_CAPTIONOKBTN;
  2336. if (Parent)
  2337. Style |= WS_POPUP;
  2338. {
  2339. RECT r;
  2340. GetWorkArea(p,&r);
  2341. x = r.left;
  2342. y = r.top;
  2343. Width = r.right - r.left;
  2344. Height = r.bottom - r.top;
  2345. }
  2346. #else
  2347. Style |= WS_OVERLAPPEDWINDOW;
  2348. y = x = CW_USEDEFAULT;
  2349. Width = WinUnitToPixelX(p,p->WinWidth);
  2350. Height = WinUnitToPixelY(p,p->WinHeight);
  2351. #endif
  2352. Wnd = CreateWindowEx(ExStyle,WinClass.lpszClassName,LangStr(p->Node.Class,NODE_NAME),Style,x,y,Width,Height,
  2353. Parent?Parent->Wnd:NULL,NULL,WinClass.hInstance,p);
  2354. if (Wnd)
  2355. {
  2356. if (p->Parent)
  2357. {
  2358. p->Parent->Child = p;
  2359. EnableWindow(p->Parent->Wnd,0);
  2360. }
  2361. else
  2362. Main = p;
  2363. while (p->Wnd && GetMessage(&Msg, NULL, 0, 0)) 
  2364. HandleMessage(p,&Msg);
  2365. if (Main == p)
  2366. Main = NULL;
  2367. }
  2368. ThreadPriority(NULL,Priority);
  2369. return p->Result;
  2370. }
  2371. static int Create(win* p)
  2372. {
  2373. UpdateDPI(p); // with NULL Wnd, because we need ScreenWidth
  2374. p->Smartphone = QueryPlatform(PLATFORM_TYPENO) == TYPE_SMARTPHONE;
  2375. p->Popup = Popup;
  2376. p->Closed = 1;
  2377. return ERR_NONE;
  2378. }
  2379. static const nodedef Win = 
  2380. {
  2381. CF_ABSTRACT,
  2382. WIN_CLASS,
  2383. NODE_CLASS,
  2384. PRI_DEFAULT,
  2385. (nodecreate)Create
  2386. };
  2387. void Win_Init()
  2388. {
  2389. HMODULE Module = Context()->LoadModule;
  2390. if (!Module) Module = GetModuleHandle(NULL);
  2391. InitCommonControls();
  2392. WidcommAudio_Init();
  2393. stprintf_s(WinClassName,TSIZEOF(WinClassName),T("%s_Win"),Context()->ProgramName);
  2394. memset(&WinClass,0,sizeof(WinClass));
  2395.     WinClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  2396.     WinClass.lpfnWndProc = Proc;
  2397.     WinClass.cbClsExtra = 0;
  2398.     WinClass.cbWndExtra = 0;
  2399.     WinClass.hInstance = Module;
  2400. WinClass.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(WIN_ICON));
  2401.     WinClass.hCursor = WinCursorArrow();
  2402.     WinClass.hbrBackground = NULL;
  2403.     WinClass.lpszMenuName = 0;
  2404.     WinClass.lpszClassName = WinClassName;
  2405. RegisterClass(&WinClass);
  2406. memset(&DialogClass,0,sizeof(DialogClass));
  2407.     DialogClass.style = CS_HREDRAW | CS_VREDRAW;
  2408.     DialogClass.lpfnWndProc = DialogProc;
  2409.     DialogClass.cbClsExtra = 0;
  2410.     DialogClass.cbWndExtra = 0;
  2411.     DialogClass.hInstance = Module;
  2412.     DialogClass.hCursor = WinCursorArrow();
  2413. #if defined(TARGET_WINCE)
  2414. DialogClass.hbrBackground = GetSysColorBrush(COLOR_STATIC);
  2415. #else
  2416. DialogClass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
  2417. #endif
  2418.     DialogClass.lpszMenuName = 0;
  2419.     DialogClass.lpszClassName = T("DialogBase");
  2420. RegisterClass(&DialogClass);
  2421. memset(&FontCache,0,sizeof(FontCache));
  2422. #if defined(TARGET_WINCE)
  2423. if (Context()->ProgramId >= 3 && !QueryAdvanced(ADVANCED_OLDSHELL))
  2424. {
  2425. AygShell = LoadLibrary(T("aygshell.dll"));
  2426. *(FARPROC*)&FuncSHCreateMenuBar = GetProcAddress(AygShell,T("SHCreateMenuBar"));
  2427. *(FARPROC*)&FuncSHInitDialog = GetProcAddress(AygShell,T("SHInitDialog"));
  2428. *(FARPROC*)&FuncSHFullScreen = GetProcAddress(AygShell,T("SHFullScreen"));
  2429. *(FARPROC*)&FuncSHHandleWMActivate = GetProcAddress(AygShell,MAKEINTRESOURCE(84));
  2430. *(FARPROC*)&FuncSHHandleWMSettingChange = GetProcAddress(AygShell,MAKEINTRESOURCE(83));
  2431. *(FARPROC*)&FuncSHSendBackToFocusWindow = GetProcAddress(AygShell,MAKEINTRESOURCE(97));
  2432. }
  2433. CoreDLL = LoadLibrary(T("coredll.dll"));
  2434. *(FARPROC*)&FuncUnregisterFunc1 = GetProcAddress(CoreDLL,T("UnregisterFunc1"));
  2435. *(FARPROC*)&FuncAllKeys = GetProcAddress(CoreDLL,T("AllKeys")); //MAKEINTRESOURCE(1453));
  2436. *(FARPROC*)&FuncSipShowIM = GetProcAddress(CoreDLL,T("SipShowIM"));
  2437. *(FARPROC*)&FuncSipGetInfo = GetProcAddress(CoreDLL,T("SipGetInfo"));
  2438. #endif
  2439. NodeRegisterClass(&Win);
  2440. QueryKey_Init();
  2441. OpenFile_Init();
  2442. Interface_Init();
  2443. PlaylistWin_Init();
  2444. }
  2445. void Win_Done()
  2446. {
  2447. int No;
  2448. Interface_Done();
  2449. PlaylistWin_Done();
  2450. QueryKey_Done();
  2451. OpenFile_Done();
  2452. NodeUnRegisterClass(WIN_CLASS);
  2453. for (No=0;No<MAXFONTSIZE;++No)
  2454. {
  2455. if (FontCache[No][0])
  2456. DeleteObject(FontCache[No][0]);
  2457. if (FontCache[No][1])
  2458. DeleteObject(FontCache[No][1]);
  2459. }
  2460. UnregisterClass(DialogClass.lpszClassName,DialogClass.hInstance);
  2461. UnregisterClass(WinClass.lpszClassName,WinClass.hInstance);
  2462. WidcommAudio_Done();
  2463. #if defined(TARGET_WINCE)
  2464. if (CoreDLL)
  2465. FreeLibrary(CoreDLL);
  2466. if (AygShell)
  2467. FreeLibrary(AygShell);
  2468. #endif
  2469. }
  2470. void WinShowHTML(const tchar_t* Name)
  2471. {
  2472. SHELLEXECUTEINFO Info;
  2473. tchar_t Path[MAXPATH];
  2474. tchar_t Base[MAXPATH];
  2475. tchar_t* p;
  2476. GetModuleFileName(NULL,Base,MAXPATH);
  2477. p = tcsrchr(Base,'\');
  2478. if (p) *p=0;
  2479. AbsPath(Path,TSIZEOF(Path),Name,Base);
  2480. memset(&Info,0,sizeof(Info));
  2481. Info.cbSize = sizeof(Info);
  2482. Info.lpVerb = T("open");
  2483. Info.lpFile = Path;
  2484. Info.nShow = SW_SHOW;
  2485. DIASet(DIA_TASKBAR,DIA_TASKBAR);
  2486. ShellExecuteEx(&Info);
  2487. }
  2488. #endif