managerView.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994
  1. #include "main.h"
  2. #include "./managerView.h"
  3. #define MANAGERVIEW_PROP L"NullsoftDevicesManagerViewProp"
  4. #define VIEW_OFFSET_LEFT_PX 0
  5. #define VIEW_OFFSET_TOP_PX 0
  6. #define VIEW_OFFSET_RIGHT_PX 2
  7. #define VIEW_OFFSET_BOTTOM_PX -1
  8. #define DISCOVER_BUTTON_MIN_HEIGHT_PX 18
  9. #define DISCOVER_BUTTON_MIN_WIDTH_PX 72
  10. #define DISCOVER_BUTTON_EXTRA_SPACE_DLU 8
  11. #define DISCOVER_BUTTON_SPACING_RIGHT_DLU 6
  12. #define ZOOM_SLIDER_SPACING_LEFT_DLU 6
  13. #define BOTTOM_BAR_OFFSET_TOP_DLU 2
  14. #define MANAGERVIEW_WIDGET_ID 10000
  15. #define MANAGERVIEW_STATUSBAR_ID 10001
  16. static ATOM MANAGERVIEW_ATOM = 0;
  17. typedef
  18. enum ManagerViewState
  19. {
  20. MANAGERVIEW_STATE_FROZEN_UI = (1 << 0),
  21. } WelcomeViewState;
  22. DEFINE_ENUM_FLAG_OPERATORS(ManagerViewState);
  23. #define MANAGERVIEW_IS_FROZEN(_view) (0 != (MANAGERVIEW_STATE_FROZEN_UI & (_view)->state))
  24. #define MANAGERVIEW_FREEZE(_view) (((_view)->state) |= MANAGERVIEW_STATE_FROZEN_UI)
  25. #define MANAGERVIEW_THAW(_view) (((_view)->state) &= ~MANAGERVIEW_STATE_FROZEN_UI)
  26. #define MANAGERVIEW_DLU_TO_HORZ_PX(_view, _dlu) MulDiv((_dlu), (_view)->unitSize.cx, 4)
  27. #define MANAGERVIEW_DLU_TO_VERT_PX(_view, _dlu) MulDiv((_dlu), (_view)->unitSize.cy, 8)
  28. #define MANAGERVIEW_REGISTER_WIDGET(_widgetWindow) (SetWindowLongPtrW((_widgetWindow), GWLP_ID, MANAGERVIEW_WIDGET_ID))
  29. #define MANAGERVIEW_WIDGET(_viewWindow) (GetDlgItem((_viewWindow), MANAGERVIEW_WIDGET_ID))
  30. #define MANAGERVIEW_STATUS_BAR(_viewWindow) (GetDlgItem((_viewWindow), MANAGERVIEW_STATUSBAR_ID))
  31. #define MANAGERVIEW_DISCOVER_BUTTON(_viewWindow) (GetDlgItem((_viewWindow), IDC_BUTTON_DISCOVER))
  32. #define MANAGERVIEW_ZOOM_SLIDER(_viewWindow) (GetDlgItem((_viewWindow), IDC_SLIDER_ZOOM))
  33. typedef struct ManagerView
  34. {
  35. ManagerViewState state;
  36. WidgetStyle widgetStyle;
  37. HFONT font;
  38. HFONT systemFont;
  39. COLORREF backColor;
  40. COLORREF textColor;
  41. COLORREF borderColor;
  42. HBRUSH backBrush;
  43. SIZE unitSize;
  44. BOOL devicesPresent;
  45. size_t deviceHandler;
  46. HRGN updateRegion;
  47. POINT updateOffset;
  48. unsigned int discoveryStatus;
  49. } ManagerView;
  50. #define MANAGERVIEW(_hwnd) ((ManagerView*)GetPropW((_hwnd), MAKEINTATOM(MANAGERVIEW_ATOM)))
  51. #define MANAGERVIEW_RET_VOID(_view, _hwnd) { (_view) = MANAGERVIEW((_hwnd)); if (NULL == (_view)) return; }
  52. #define MANAGERVIEW_RET_VAL(_view, _hwnd, _error) { (_view) = MANAGERVIEW((_hwnd)); if (NULL == (_view)) return (_error); }
  53. static INT_PTR CALLBACK
  54. ManagerView_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  55. static void CALLBACK
  56. ManagerView_PluginUnloadCb()
  57. {
  58. if (0 != MANAGERVIEW_ATOM)
  59. {
  60. GlobalDeleteAtom(MANAGERVIEW_ATOM);
  61. MANAGERVIEW_ATOM = 0;
  62. }
  63. }
  64. HWND ManagerView_CreateWindow(HWND parentWindow)
  65. {
  66. if (0 == MANAGERVIEW_ATOM)
  67. {
  68. MANAGERVIEW_ATOM = GlobalAddAtom(MANAGERVIEW_PROP);
  69. if (0 == MANAGERVIEW_ATOM)
  70. return NULL;
  71. Plugin_RegisterUnloadCallback(ManagerView_PluginUnloadCb);
  72. }
  73. HWND hwnd = WASABI_API_CREATEDIALOGPARAMW((INT_PTR)IDD_MANAGER_VIEW, parentWindow,
  74. ManagerView_DialogProc, (LPARAM)0L);
  75. return hwnd;
  76. }
  77. static void
  78. ManagerView_Layout(HWND hwnd, BOOL redraw)
  79. {
  80. ManagerView *self = NULL;
  81. RECT clientRect, elementRect;
  82. LONG bottomBarHeight = 0, buttonWidth = 0, sliderWidth = 0;
  83. MANAGERVIEW_RET_VOID(self, hwnd);
  84. GetClientRect(hwnd, &clientRect);
  85. clientRect.left += VIEW_OFFSET_LEFT_PX;
  86. clientRect.top += VIEW_OFFSET_TOP_PX;
  87. clientRect.right -= VIEW_OFFSET_RIGHT_PX;
  88. clientRect.bottom -= VIEW_OFFSET_BOTTOM_PX;
  89. HDWP hdwp = BeginDeferWindowPos(4);
  90. if (NULL == hdwp)
  91. return;
  92. UINT swpFlags = SWP_NOACTIVATE | SWP_NOZORDER;
  93. if (FALSE == redraw)
  94. swpFlags |= SWP_NOREDRAW;
  95. HWND buttonWindow = MANAGERVIEW_DISCOVER_BUTTON(hwnd);
  96. if (NULL != buttonWindow)
  97. {
  98. if (FALSE != GetWindowRect(buttonWindow, &elementRect))
  99. {
  100. wchar_t buffer[128] = {0};
  101. GetWindowText(buttonWindow, buffer, ARRAYSIZE(buffer));
  102. LRESULT idealSize = MLSkinnedButton_GetIdealSize(buttonWindow, buffer);
  103. hdwp = DeferWindowPos(hdwp, buttonWindow, NULL, clientRect.left + 1,
  104. clientRect.bottom - WASABI_API_APP->getScaleY(HIWORD(idealSize)) - WASABI_API_APP->getScaleY(1),
  105. RECTWIDTH(elementRect), WASABI_API_APP->getScaleY(HIWORD(idealSize)), swpFlags);
  106. bottomBarHeight = WASABI_API_APP->getScaleY(HIWORD(idealSize));
  107. buttonWidth = RECTWIDTH(elementRect);
  108. }
  109. }
  110. HWND sliderWindow = MANAGERVIEW_ZOOM_SLIDER(hwnd);
  111. if (NULL != sliderWindow)
  112. {
  113. if (0 != (WS_VISIBLE & GetWindowStyle(sliderWindow)) &&
  114. FALSE != GetWindowRect(sliderWindow, &elementRect))
  115. {
  116. hdwp = DeferWindowPos(hdwp, sliderWindow, NULL, clientRect.right - RECTWIDTH(elementRect),
  117. clientRect.bottom - RECTHEIGHT(elementRect),
  118. RECTWIDTH(elementRect), RECTHEIGHT(elementRect), swpFlags);
  119. sliderWidth = RECTWIDTH(elementRect);
  120. }
  121. }
  122. HWND statusBar = MANAGERVIEW_STATUS_BAR(hwnd);
  123. if (NULL != statusBar)
  124. {
  125. long statusBarHeight = 0;
  126. CopyRect(&elementRect, &clientRect);
  127. if (0 != buttonWidth)
  128. {
  129. elementRect.left += buttonWidth;
  130. elementRect.left += MANAGERVIEW_DLU_TO_HORZ_PX(self, DISCOVER_BUTTON_SPACING_RIGHT_DLU);
  131. if (elementRect.left > clientRect.right)
  132. elementRect.left = clientRect.right;
  133. }
  134. if (0 != sliderWidth)
  135. {
  136. elementRect.right -= sliderWidth;
  137. elementRect.right -= MANAGERVIEW_DLU_TO_HORZ_PX(self, ZOOM_SLIDER_SPACING_LEFT_DLU);
  138. if (elementRect.left > elementRect.right)
  139. elementRect.right = elementRect.left;
  140. }
  141. statusBarHeight = STATUSBAR_GET_IDEAL_HEIGHT(statusBar);
  142. if (statusBarHeight > bottomBarHeight)
  143. statusBarHeight = 0;
  144. elementRect.top = elementRect.bottom - statusBarHeight - WASABI_API_APP->getScaleY(3);
  145. elementRect.bottom = elementRect.top + statusBarHeight;
  146. hdwp = DeferWindowPos(hdwp, statusBar, NULL, elementRect.left, elementRect.top,
  147. RECTWIDTH(elementRect), RECTHEIGHT(elementRect), swpFlags);
  148. }
  149. HWND widgetWindow = MANAGERVIEW_WIDGET(hwnd);
  150. if (NULL != widgetWindow)
  151. {
  152. CopyRect(&elementRect, &clientRect);
  153. if (0 != bottomBarHeight)
  154. {
  155. elementRect.bottom -= (bottomBarHeight + WASABI_API_APP->getScaleY(4));
  156. }
  157. Graphics_ClampRect(&elementRect, &clientRect);
  158. if (NULL != hdwp)
  159. {
  160. hdwp = DeferWindowPos(hdwp, widgetWindow, NULL, elementRect.left, elementRect.top,
  161. RECTWIDTH(elementRect), RECTHEIGHT(elementRect), swpFlags);
  162. }
  163. }
  164. if (NULL != hdwp)
  165. EndDeferWindowPos(hdwp);
  166. }
  167. static BOOL
  168. ManagerView_Paint(HWND hwnd, HDC hdc, const RECT *paintRect, BOOL erase)
  169. {
  170. ManagerView *self;
  171. MANAGERVIEW_RET_VAL(self, hwnd, FALSE);
  172. if (FALSE != erase)
  173. {
  174. HRGN fillRegion;
  175. fillRegion = CreateRectRgnIndirect(paintRect);
  176. FillRgn(hdc, fillRegion, self->backBrush);
  177. DeleteObject(fillRegion);
  178. }
  179. return TRUE;
  180. }
  181. static void
  182. ManagerView_UpdateSkin(HWND hwnd)
  183. {
  184. ManagerView *self;
  185. MANAGERVIEW_RET_VOID(self, hwnd);
  186. BOOL styleChanged = FALSE;
  187. COLORREF color = Graphics_GetSkinColor(WADLG_WNDBG);
  188. if (color != self->backColor || NULL == self->backBrush)
  189. {
  190. self->backColor = color;
  191. self->backBrush = CreateSolidBrush(self->backColor);
  192. styleChanged = TRUE;
  193. }
  194. color = Graphics_GetSkinColor(WADLG_WNDFG);
  195. if (self->textColor != color)
  196. {
  197. self->textColor = color;
  198. styleChanged = TRUE;
  199. }
  200. color = Graphics_GetSkinColor(WADLG_HILITE);
  201. if (self->borderColor != color)
  202. {
  203. self->borderColor = color;
  204. styleChanged = TRUE;
  205. }
  206. if (FALSE != WidgetStyle_UpdateDefaultColors(&self->widgetStyle))
  207. styleChanged = TRUE;
  208. if (FALSE != styleChanged)
  209. {
  210. HWND controlWindow = MANAGERVIEW_WIDGET(hwnd);
  211. if (NULL != controlWindow)
  212. {
  213. WIDGET_STYLE_COLOR_CHANGED(controlWindow);
  214. InvalidateRect(controlWindow, NULL, TRUE);
  215. }
  216. controlWindow = MANAGERVIEW_STATUS_BAR(hwnd);
  217. if (NULL != controlWindow)
  218. {
  219. STATUSBAR_SET_TEXT_COLOR(controlWindow, self->textColor, FALSE);
  220. STATUSBAR_SET_BACK_COLOR(controlWindow, self->backColor, FALSE);
  221. STATUSBAR_SET_BACK_BRUSH(controlWindow, self->backBrush, FALSE);
  222. }
  223. }
  224. }
  225. static BOOL
  226. ManagerView_GetIdealButtonSize(HWND buttonWindow, SIZE *buttonSize)
  227. {
  228. if (NULL == buttonWindow || NULL == buttonSize)
  229. return FALSE;
  230. LRESULT skinSize = MLSkinnedButton_GetIdealSize(buttonWindow, NULL);
  231. if (0 != skinSize)
  232. {
  233. buttonSize->cx = LOWORD(skinSize);
  234. buttonSize->cy = HIWORD(skinSize);
  235. return TRUE;
  236. }
  237. buttonSize->cx = 0;
  238. buttonSize->cy = 0;
  239. if (FALSE != SendMessageW(buttonWindow, BCM_GETIDEALSIZE, 0, (LPARAM)buttonSize))
  240. return TRUE;
  241. return FALSE;
  242. }
  243. static BOOL
  244. ManagerView_UpdateDiscoverButtonFont(HWND hwnd, HFONT font, SIZE *size)
  245. {
  246. ManagerView *self;
  247. SIZE buttonSize;
  248. MANAGERVIEW_RET_VAL(self, hwnd, FALSE);
  249. HWND buttonWindow = MANAGERVIEW_DISCOVER_BUTTON(hwnd);
  250. if (NULL == buttonWindow)
  251. return FALSE;
  252. SendMessage(buttonWindow, WM_SETFONT, (WPARAM)font, MAKELPARAM(0,0));
  253. if (FALSE == ManagerView_GetIdealButtonSize(buttonWindow, &buttonSize))
  254. {
  255. RECT buttonRect;
  256. if (FALSE == GetWindowRect(buttonWindow, &buttonRect))
  257. return FALSE;
  258. buttonSize.cx = RECTWIDTH(buttonRect);
  259. buttonSize.cy = RECTHEIGHT(buttonRect);
  260. }
  261. buttonSize.cx += MANAGERVIEW_DLU_TO_HORZ_PX(self, DISCOVER_BUTTON_EXTRA_SPACE_DLU);
  262. if (buttonSize.cx < DISCOVER_BUTTON_MIN_WIDTH_PX)
  263. buttonSize.cx = DISCOVER_BUTTON_MIN_WIDTH_PX;
  264. if (buttonSize.cy < DISCOVER_BUTTON_MIN_HEIGHT_PX)
  265. buttonSize.cy = DISCOVER_BUTTON_MIN_HEIGHT_PX;
  266. BOOL result = SetWindowPos(buttonWindow, NULL, 0, 0, buttonSize.cx, buttonSize.cy,
  267. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW);
  268. if (FALSE == result)
  269. return FALSE;
  270. if (NULL != size)
  271. *size = buttonSize;
  272. return TRUE;
  273. }
  274. static void
  275. ManagerView_UpdateFont(HWND hwnd, BOOL redraw)
  276. {
  277. HWND controlWindow = NULL;
  278. ManagerView *self = NULL;
  279. MANAGERVIEW_RET_VOID(self, hwnd);
  280. if (FALSE == Graphics_GetWindowBaseUnits(hwnd, &self->unitSize.cx, &self->unitSize.cy))
  281. {
  282. self->unitSize.cx = 6;
  283. self->unitSize.cy = 13;
  284. }
  285. if (FALSE != WidgetStyle_UpdateDefaultFonts(&self->widgetStyle, self->font, self->unitSize.cx, self->unitSize.cy))
  286. {
  287. controlWindow = MANAGERVIEW_WIDGET(hwnd);
  288. if (NULL != controlWindow)
  289. WIDGET_STYLE_FONT_CHANGED(controlWindow);
  290. }
  291. ManagerView_UpdateDiscoverButtonFont(hwnd, self->font, NULL);
  292. controlWindow = MANAGERVIEW_STATUS_BAR(hwnd);
  293. if (NULL != controlWindow)
  294. SendMessage(controlWindow, WM_SETFONT, (WPARAM)self->font, 0L);
  295. if (NULL != redraw)
  296. {
  297. SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
  298. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE |SWP_NOMOVE |SWP_FRAMECHANGED | SWP_NOREDRAW);
  299. RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE);
  300. }
  301. }
  302. static void
  303. ManagerView_UpdateDiscoveryStatus(HWND hwnd, BOOL discoveryActive)
  304. {
  305. ManagerView *self;
  306. MANAGERVIEW_RET_VOID(self, hwnd);
  307. HWND statusBar = MANAGERVIEW_STATUS_BAR(hwnd);
  308. if (NULL == statusBar)
  309. return;
  310. if (FALSE != discoveryActive)
  311. {
  312. wchar_t buffer[512] = {0};
  313. WASABI_API_LNGSTRINGW_BUF(IDS_STATUS_DISCOVERY_ACTIVE, buffer, ARRAYSIZE(buffer));
  314. if (STATUS_ERROR == self->discoveryStatus)
  315. self->discoveryStatus = STATUSBAR_ADD_STATUS(statusBar, buffer);
  316. else
  317. {
  318. STATUSBAR_SET_STATUS_TEXT(statusBar, self->discoveryStatus, buffer);
  319. STATUSBAR_MOVE_STATUS(statusBar, self->discoveryStatus, STATUS_MOVE_TOP);
  320. }
  321. }
  322. else
  323. {
  324. if (STATUS_ERROR != self->discoveryStatus)
  325. {
  326. STATUSBAR_REMOVE_STATUS(statusBar, self->discoveryStatus);
  327. self->discoveryStatus = STATUS_ERROR;
  328. }
  329. }
  330. }
  331. static HWND
  332. ManagerView_CreateServiceErrorWidget(HWND hwnd)
  333. {
  334. return InfoWidget_CreateWindow(WIDGET_TYPE_SERVICE_ERROR,
  335. MAKEINTRESOURCE(IDS_INFOWIDGET_TITLE),
  336. MAKEINTRESOURCE(IDS_DEVICE_SERVICE_NOT_FOUND),
  337. NULL,
  338. hwnd, 0, 0, 0, 0, TRUE, 0);
  339. }
  340. static HWND
  341. ManagerView_CreateViewErrorWidget(HWND hwnd)
  342. {
  343. return InfoWidget_CreateWindow(WIDGET_TYPE_VIEW_ERROR,
  344. MAKEINTRESOURCE(IDS_INFOWIDGET_TITLE),
  345. MAKEINTRESOURCE(IDS_CREATE_MANAGER_VIEW_FAILED),
  346. NULL,
  347. hwnd, 0, 0, 0, 0, TRUE, 0);
  348. }
  349. static HWND
  350. ManagerView_UpdateWidget(HWND hwnd)
  351. {
  352. ManagerView *self;
  353. unsigned int widgetType, requiredType;
  354. unsigned int windowStyle;
  355. MANAGERVIEW_RET_VAL(self, hwnd, NULL);
  356. HWND widgetWindow = MANAGERVIEW_WIDGET(hwnd);
  357. if (NULL == widgetWindow)
  358. widgetType = WIDGET_TYPE_UNKNOWN;
  359. else
  360. widgetType = WIDGET_GET_TYPE(widgetWindow);
  361. if (FALSE != self->devicesPresent)
  362. requiredType = WIDGET_TYPE_LIST;
  363. else
  364. {
  365. requiredType = (NULL != WASABI_API_DEVICES) ?
  366. WIDGET_TYPE_WELCOME :
  367. WIDGET_TYPE_SERVICE_ERROR;
  368. }
  369. if (widgetType == requiredType)
  370. return widgetWindow;
  371. windowStyle = GetWindowStyle(hwnd);
  372. if (0 != (WS_VISIBLE & windowStyle))
  373. SetWindowStyle(hwnd, windowStyle & ~WS_VISIBLE);
  374. if (NULL != widgetWindow)
  375. {
  376. SetWindowLongPtr(widgetWindow, GWLP_ID, 0);
  377. WIDGET_FREEZE(widgetWindow);
  378. DestroyWindow(widgetWindow);
  379. }
  380. switch(requiredType)
  381. {
  382. case WIDGET_TYPE_SERVICE_ERROR:
  383. widgetWindow = ManagerView_CreateServiceErrorWidget(hwnd);
  384. break;
  385. case WIDGET_TYPE_WELCOME:
  386. widgetWindow = WelcomeWidget_CreateWindow(hwnd, 0, 0, 0, 0, TRUE, 0);
  387. break;
  388. case WIDGET_TYPE_LIST:
  389. widgetWindow = ListWidget_CreateWindow(hwnd, 0, 0, 0, 0, TRUE, 0);
  390. break;
  391. default:
  392. widgetWindow = NULL;
  393. break;
  394. }
  395. if (NULL == widgetWindow)
  396. widgetWindow = ManagerView_CreateViewErrorWidget(hwnd);
  397. if (NULL != widgetWindow)
  398. {
  399. if (FALSE != MANAGERVIEW_IS_FROZEN(self))
  400. WIDGET_FREEZE(widgetWindow);
  401. MANAGERVIEW_REGISTER_WIDGET(widgetWindow);
  402. WIDGET_SET_STYLE(widgetWindow, &self->widgetStyle);
  403. }
  404. SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
  405. SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW | SWP_FRAMECHANGED);
  406. if (NULL != widgetWindow)
  407. {
  408. ShowWindow(widgetWindow, SW_SHOWNA);
  409. SetWindowPos(widgetWindow, HWND_TOP, 0, 0, 0, 0,
  410. SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
  411. }
  412. if (0 != (WS_VISIBLE & windowStyle))
  413. {
  414. windowStyle = GetWindowStyle(hwnd);
  415. if (0 == (WS_VISIBLE & windowStyle))
  416. {
  417. windowStyle |= WS_VISIBLE;
  418. SetWindowStyle(hwnd, windowStyle);
  419. }
  420. }
  421. if (0 != (WS_VISIBLE & windowStyle))
  422. {
  423. RECT rect;
  424. GetClientRect(hwnd, &rect);
  425. RedrawWindow(hwnd, &rect, NULL,
  426. RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ERASENOW | RDW_ALLCHILDREN);
  427. }
  428. return widgetWindow;
  429. }
  430. static void
  431. ManagerView_StartDiscovery(HWND hwnd, BOOL silent)
  432. {
  433. Plugin_BeginDiscovery();
  434. }
  435. static BOOL
  436. ManagerView_CheckDevicesPresent()
  437. {
  438. ifc_deviceobjectenum *enumerator = 0;
  439. ifc_deviceobject *object = 0;
  440. ifc_device *device = 0;
  441. BOOL devicesPresent = FALSE;
  442. if (NULL == WASABI_API_DEVICES ||
  443. FAILED(WASABI_API_DEVICES->DeviceEnumerate(&enumerator)))
  444. {
  445. return FALSE;
  446. }
  447. while(S_OK == enumerator->Next(&object, 1, NULL))
  448. {
  449. if (SUCCEEDED(object->QueryInterface(IFC_Device, (void**)&device)))
  450. {
  451. if(FALSE == device->GetHidden() &&
  452. // excludes 'cloud' devices from appearing
  453. lstrcmpiA(device->GetConnection(), "cloud"))
  454. devicesPresent = TRUE;
  455. device->Release();
  456. }
  457. object->Release();
  458. if (FALSE != devicesPresent)
  459. break;
  460. }
  461. enumerator->Release();
  462. return devicesPresent;
  463. }
  464. static void
  465. ManagerView_AddDevice(HWND hwnd, ifc_device *device)
  466. {
  467. ManagerView *self;
  468. MANAGERVIEW_RET_VOID(self, hwnd);
  469. if (FALSE != self->devicesPresent)
  470. return;
  471. self->devicesPresent = ManagerView_CheckDevicesPresent();
  472. if (FALSE != self->devicesPresent)
  473. ManagerView_UpdateWidget(hwnd);
  474. }
  475. static void
  476. ManagerView_RemoveDevice(HWND hwnd, ifc_device *device)
  477. {
  478. ManagerView *self;
  479. MANAGERVIEW_RET_VOID(self, hwnd);
  480. if (FALSE == self->devicesPresent)
  481. return;
  482. self->devicesPresent = ManagerView_CheckDevicesPresent();
  483. if (FALSE == self->devicesPresent)
  484. ManagerView_UpdateWidget(hwnd);
  485. }
  486. static void
  487. ManagerView_DeviceCb(ifc_device *device, DeviceEvent eventId, void *user)
  488. {
  489. HWND hwnd = (HWND)user;
  490. switch(eventId)
  491. {
  492. case Event_DeviceAdded:
  493. ManagerView_AddDevice(hwnd, device);
  494. break;
  495. case Event_DeviceRemoved:
  496. ManagerView_RemoveDevice(hwnd, device);
  497. break;
  498. }
  499. }
  500. static void
  501. ManagerView_DiscoveryCb(api_devicemanager *manager, DeviceDiscoveryEvent eventId, void *user)
  502. {
  503. HWND hwnd = (HWND)user;
  504. switch(eventId)
  505. {
  506. case Event_DiscoveryStarted:
  507. ManagerView_UpdateDiscoveryStatus(hwnd, TRUE);
  508. break;
  509. case Event_DiscoveryFinished:
  510. ManagerView_UpdateDiscoveryStatus(hwnd, FALSE);
  511. break;
  512. }
  513. }
  514. static BOOL
  515. ManagerView_RegisterDeviceHandler(HWND hwnd)
  516. {
  517. ManagerView *self;
  518. DeviceEventCallbacks callbacks;
  519. MANAGERVIEW_RET_VAL(self, hwnd, FALSE);
  520. if (0 != self->deviceHandler)
  521. return FALSE;
  522. HWND eventRelay = Plugin_GetEventRelayWindow();
  523. if (NULL == eventRelay)
  524. return FALSE;
  525. ZeroMemory(&callbacks, sizeof(callbacks));
  526. callbacks.deviceCb = ManagerView_DeviceCb;
  527. callbacks.discoveryCb = ManagerView_DiscoveryCb;
  528. self->deviceHandler = EVENTRELAY_REGISTER_HANDLER(eventRelay, &callbacks, hwnd);
  529. return (0 != self->deviceHandler);
  530. }
  531. static void
  532. ManagerView_OnDisplayChanged(HWND hwnd, INT bpp, INT dpi_x, INT dpi_y)
  533. {
  534. ManagerView *self = NULL;
  535. MANAGERVIEW_RET_VOID(self, hwnd);
  536. if (FALSE != MANAGERVIEW_IS_FROZEN(self))
  537. return;
  538. ManagerView_UpdateSkin(hwnd);
  539. RECT rc;
  540. GetClientRect(hwnd, &rc);
  541. RedrawWindow(hwnd, &rc, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN | RDW_ERASENOW | RDW_UPDATENOW);
  542. ManagerView_Layout(hwnd, TRUE);
  543. }
  544. static INT_PTR
  545. ManagerView_OnInitDialog(HWND hwnd, HWND focusWindow, LPARAM param)
  546. {
  547. ManagerView *self = (ManagerView*)malloc(sizeof(ManagerView));
  548. if (NULL != self)
  549. {
  550. ZeroMemory(self, sizeof(ManagerView));
  551. if (FALSE == SetProp(hwnd, MAKEINTATOM(MANAGERVIEW_ATOM), self))
  552. {
  553. free(self);
  554. self = NULL;
  555. }
  556. }
  557. if (NULL == self)
  558. {
  559. DestroyWindow(hwnd);
  560. return 0;
  561. }
  562. MANAGERVIEW_FREEZE(self);
  563. ManagerView_RegisterDeviceHandler(hwnd);
  564. self->devicesPresent = ManagerView_CheckDevicesPresent();
  565. MLSkinWindow2(Plugin_GetLibraryWindow(), hwnd, SKINNEDWND_TYPE_DIALOG,
  566. SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS);
  567. HWND discoverButton = MANAGERVIEW_DISCOVER_BUTTON(hwnd);
  568. if (NULL != discoverButton)
  569. {
  570. MLSkinWindow2(Plugin_GetLibraryWindow(), discoverButton, SKINNEDWND_TYPE_BUTTON,
  571. SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS);
  572. ShowWindow(discoverButton, SW_SHOW);
  573. EnableWindow(discoverButton, TRUE);
  574. }
  575. HWND statusBar = StatusBar_CreateWindow(0, NULL, WS_VISIBLE, 0, 0, 0, 0, hwnd, MANAGERVIEW_STATUSBAR_ID);
  576. if (NULL != statusBar)
  577. {
  578. MLSkinWindow2(Plugin_GetLibraryWindow(), statusBar, SKINNEDWND_TYPE_AUTO,
  579. SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS);
  580. }
  581. self->discoveryStatus = STATUS_ERROR;
  582. if (S_OK == WASABI_API_DEVICES->IsDiscoveryActive())
  583. ManagerView_UpdateDiscoveryStatus(hwnd, TRUE);
  584. ManagerView_UpdateFont(hwnd, FALSE);
  585. ManagerView_UpdateSkin(hwnd);
  586. HWND widgetWindow = ManagerView_UpdateWidget(hwnd);
  587. MANAGERVIEW_THAW(self);
  588. if (NULL != widgetWindow)
  589. WIDGET_THAW(widgetWindow);
  590. PostMessage(hwnd, WM_DISPLAYCHANGE, 0, 0);
  591. return 0;
  592. }
  593. static void
  594. ManagerView_OnDestroy(HWND hwnd)
  595. {
  596. ManagerView *self = MANAGERVIEW(hwnd);
  597. RemoveProp(hwnd, MAKEINTATOM(MANAGERVIEW_ATOM));
  598. if (NULL == self)
  599. return;
  600. MANAGERVIEW_FREEZE(self);
  601. if (0 != self->deviceHandler)
  602. {
  603. HWND eventRelay = Plugin_GetEventRelayWindow();
  604. if (NULL != eventRelay)
  605. {
  606. EVENTRELAY_UNREGISTER_HANDLER(eventRelay, self->deviceHandler);
  607. }
  608. }
  609. if (NULL != self->systemFont)
  610. DeleteObject(self->systemFont);
  611. if (NULL != self->backBrush)
  612. DeleteObject(self->backBrush);
  613. WidgetStyle_Free(&self->widgetStyle);
  614. free(self);
  615. }
  616. static LRESULT
  617. ManagerView_OnColorDialog(HWND hwnd, HDC hdc)
  618. {
  619. ManagerView *self;
  620. self = MANAGERVIEW(hwnd);
  621. if (NULL == self)
  622. return DefWindowProcW(hwnd, WM_CTLCOLORDLG, (WPARAM)hdc, (LPARAM)hwnd);
  623. if (NULL != hdc)
  624. {
  625. SetTextColor(hdc, self->textColor);
  626. SetBkColor(hdc, self->backColor);
  627. }
  628. return (LRESULT)self->backBrush;
  629. }
  630. static void
  631. ManagerView_OnWindowPosChanged(HWND hwnd, WINDOWPOS *windowPos)
  632. {
  633. if ((SWP_NOSIZE | SWP_NOMOVE) != ((SWP_NOSIZE | SWP_NOMOVE) & windowPos->flags) ||
  634. (SWP_FRAMECHANGED & windowPos->flags))
  635. {
  636. ManagerView *self;
  637. MANAGERVIEW_RET_VOID(self, hwnd);
  638. if (FALSE != MANAGERVIEW_IS_FROZEN(self))
  639. return;
  640. ManagerView_Layout(hwnd, !(SWP_NOREDRAW & windowPos->flags));
  641. }
  642. }
  643. static void
  644. ManagerView_OnPaint(HWND hwnd)
  645. {
  646. PAINTSTRUCT ps;
  647. if (NULL != BeginPaint(hwnd, &ps))
  648. {
  649. ManagerView_Paint(hwnd, ps.hdc, &ps.rcPaint, ps.fErase);
  650. EndPaint(hwnd, &ps);
  651. }
  652. }
  653. static void
  654. ManagerView_OnPrintClient(HWND hwnd, HDC hdc, UINT options)
  655. {
  656. RECT clientRect;
  657. if (GetClientRect(hwnd, &clientRect))
  658. {
  659. ManagerView_Paint(hwnd, hdc, &clientRect, TRUE);
  660. }
  661. }
  662. static void
  663. ManagerView_OnSetFont(HWND hwnd, HFONT font, BOOL redraw)
  664. {
  665. ManagerView *self = NULL;
  666. LOGFONTW prevFont = {0}, newFont = {0};
  667. MANAGERVIEW_RET_VOID(self, hwnd);
  668. if (NULL == self->font ||
  669. sizeof(LOGFONTW) != GetObjectW(self->font, sizeof(prevFont), &prevFont))
  670. {
  671. ZeroMemory(&prevFont, sizeof(prevFont));
  672. }
  673. self->font = font;
  674. if (NULL == self->font)
  675. {
  676. if (NULL == self->systemFont)
  677. self->systemFont = Graphics_CreateSysFont();
  678. }
  679. if (NULL == self->font ||
  680. sizeof(newFont) != GetObjectW(self->font, sizeof(newFont), &newFont))
  681. {
  682. ZeroMemory(&newFont, sizeof(newFont));
  683. }
  684. if (0 == memcmp(&prevFont, &newFont, sizeof(prevFont)) ||
  685. FALSE != MANAGERVIEW_IS_FROZEN(self))
  686. {
  687. redraw = FALSE;
  688. }
  689. ManagerView_UpdateFont(hwnd, redraw);
  690. }
  691. static HFONT
  692. ManagerView_OnGetFont(HWND hwnd)
  693. {
  694. ManagerView *self;
  695. MANAGERVIEW_RET_VAL(self, hwnd, NULL);
  696. return self->font;
  697. }
  698. static void
  699. ManagerView_OnCommand(HWND hwnd, INT commandId, INT eventId, HWND controlWindow)
  700. {
  701. switch(commandId)
  702. {
  703. case IDC_BUTTON_DISCOVER:
  704. switch(eventId)
  705. {
  706. case BN_CLICKED:
  707. ManagerView_StartDiscovery(hwnd, FALSE);
  708. break;
  709. }
  710. break;
  711. }
  712. }
  713. static void
  714. ManagerView_OnZoomSliderPosChanging(HWND hwnd, NMTRBTHUMBPOSCHANGING *sliderInfo)
  715. {
  716. HWND widgetWindow = MANAGERVIEW_WIDGET(hwnd);
  717. if (NULL != widgetWindow)
  718. WIDGET_ZOOM_SLIDER_POS_CHANGING(widgetWindow, sliderInfo);
  719. }
  720. static LRESULT
  721. ManagerView_OnNotify(HWND hwnd, NMHDR *pnmh)
  722. {
  723. return 0;
  724. }
  725. static void
  726. ManagerView_OnHorzScroll(HWND hwnd, INT action, INT trackPosition, HWND senderWindow)
  727. {
  728. HWND sliderWindow = MANAGERVIEW_ZOOM_SLIDER(hwnd);
  729. if (NULL != sliderWindow && senderWindow == sliderWindow)
  730. {
  731. NMTRBTHUMBPOSCHANGING zoomInfo;
  732. zoomInfo.hdr.code = TRBN_THUMBPOSCHANGING;
  733. zoomInfo.hdr.hwndFrom = senderWindow;
  734. zoomInfo.hdr.idFrom = IDC_SLIDER_ZOOM;
  735. zoomInfo.nReason = action;
  736. if (TB_THUMBPOSITION == action ||
  737. TB_THUMBTRACK == action)
  738. {
  739. zoomInfo.dwPos = trackPosition;
  740. }
  741. else
  742. zoomInfo.dwPos = (DWORD)SendMessage(sliderWindow, TBM_GETPOS, 0, 0L);
  743. ManagerView_OnZoomSliderPosChanging(hwnd, &zoomInfo);
  744. }
  745. }
  746. static BOOL
  747. ManagerView_OnHelp(HWND hwnd, HELPINFO *helpInfo)
  748. {
  749. HWND widgetWindow = MANAGERVIEW_WIDGET(hwnd);
  750. if (NULL != widgetWindow)
  751. {
  752. wchar_t buffer[4096] = {0};
  753. if (FALSE != WIDGET_GET_HELP_URL(widgetWindow, buffer, ARRAYSIZE(buffer)) &&
  754. MediaLibrary_ShowHelp(Plugin_GetLibraryWindow(), buffer))
  755. {
  756. return TRUE;
  757. }
  758. }
  759. return Plugin_ShowHelp();
  760. }
  761. static void
  762. ManagerView_OnSetUpdateRegion(HWND hwnd, HRGN updateRegion, POINTS regionOffset)
  763. {
  764. ManagerView *self;
  765. MANAGERVIEW_RET_VOID(self, hwnd);
  766. self->updateRegion = updateRegion;
  767. self->updateOffset.x = regionOffset.x;
  768. self->updateOffset.y = regionOffset.y;
  769. }
  770. static HWND
  771. ManagerView_OnGetZoomSlider(HWND hwnd)
  772. {
  773. return MANAGERVIEW_ZOOM_SLIDER(hwnd);
  774. }
  775. static HWND
  776. ManagerView_OnGetStatusBar(HWND hwnd)
  777. {
  778. return MANAGERVIEW_STATUS_BAR(hwnd);
  779. }
  780. static INT_PTR CALLBACK
  781. ManagerView_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  782. {
  783. switch(uMsg)
  784. {
  785. case WM_INITDIALOG: return ManagerView_OnInitDialog(hwnd, (HWND)wParam, lParam);
  786. case WM_DESTROY: ManagerView_OnDestroy(hwnd); return TRUE;
  787. case WM_CTLCOLORDLG: return ManagerView_OnColorDialog(hwnd, (HDC)wParam);
  788. case WM_PAINT: ManagerView_OnPaint(hwnd); return TRUE;
  789. case WM_PRINTCLIENT: ManagerView_OnPrintClient(hwnd, (HDC)wParam, (UINT)lParam); return TRUE;
  790. case WM_ERASEBKGND: DIALOG_RESULT(hwnd, 0);
  791. case WM_WINDOWPOSCHANGED: ManagerView_OnWindowPosChanged(hwnd, (WINDOWPOS*)lParam); return TRUE;
  792. case WM_DISPLAYCHANGE: ManagerView_OnDisplayChanged(hwnd, (INT)wParam, LOWORD(lParam), HIWORD(lParam)); return TRUE;
  793. case WM_SETFONT: ManagerView_OnSetFont(hwnd, (HFONT)wParam, LOWORD(lParam)); return TRUE;
  794. case WM_GETFONT: DIALOG_RESULT(hwnd, ManagerView_OnGetFont(hwnd));
  795. case WM_COMMAND: ManagerView_OnCommand(hwnd, LOWORD(wParam), HIWORD(wParam), (HWND)lParam); return TRUE;
  796. case WM_NOTIFY: DIALOG_RESULT(hwnd, ManagerView_OnNotify(hwnd, (NMHDR*)lParam));
  797. case WM_HSCROLL: ManagerView_OnHorzScroll(hwnd, LOWORD(wParam), (short)HIWORD(wParam), (HWND)lParam); return TRUE;
  798. case WM_HELP: DIALOG_RESULT(hwnd, ManagerView_OnHelp(hwnd, (HELPINFO*)lParam));
  799. // gen_ml flickerless drawing
  800. case WM_USER + 0x200: DIALOG_RESULT(hwnd, 1);
  801. case WM_USER + 0x201: ManagerView_OnSetUpdateRegion(hwnd, (HRGN)lParam, MAKEPOINTS(wParam)); return TRUE;
  802. case MANAGERVIEW_WM_ZOOMSLIDER: DIALOG_RESULT(hwnd, ManagerView_OnGetZoomSlider(hwnd));
  803. case MANAGERVIEW_WM_STATUSBAR: DIALOG_RESULT(hwnd, ManagerView_OnGetStatusBar(hwnd));
  804. }
  805. return 0;
  806. }