-/*\r
- * PROJECT: ReactOS Timedate Control Panel\r
- * LICENSE: GPL - See COPYING in the top level directory\r
- * FILE: lib/cpl/desk/preview.c\r
- * PURPOSE: Draws the preview control\r
- * COPYRIGHT: Copyright 2006 Eric Kohl\r
- */\r
-\r
-#include "desk.h"\r
-#include "preview.h"\r
-\r
-static const TCHAR szPreviewWndClass[] = TEXT("PreviewWndClass");\r
-\r
-typedef struct _PREVIEW_DATA\r
-{\r
- HWND hwndParent;\r
-\r
- DWORD clrDesktop;\r
- HBRUSH hbrDesktop;\r
-\r
- DWORD clrWindow;\r
- HBRUSH hbrWindow;\r
-\r
- DWORD clrScrollbar;\r
- HBRUSH hbrScrollbar;\r
-\r
- DWORD clrActiveCaptionText;\r
- DWORD clrInactiveCaptionText;\r
- DWORD clrWindowText;\r
- DWORD clrButtonText;\r
-\r
- INT cxEdge;\r
- INT cyEdge;\r
-\r
- INT cyCaption;\r
-\r
- RECT rcDesktop;\r
- RECT rcInactiveFrame;\r
- RECT rcInactiveCaption;\r
-\r
- RECT rcActiveFrame;\r
- RECT rcActiveCaption;\r
- RECT rcActiveMenuBar;\r
- RECT rcSelectedMenuItem;\r
- RECT rcActiveClient;\r
- RECT rcActiveScroll;\r
-\r
- RECT rcDialogFrame;\r
- RECT rcDialogCaption;\r
- RECT rcDialogClient;\r
-\r
- RECT rcDialogButton;\r
-\r
- LPTSTR lpInAct;\r
- LPTSTR lpAct;\r
- LPTSTR lpWinTxt;\r
- LPTSTR lpMessBox;\r
- LPTSTR lpMessText;\r
- LPTSTR lpButText;\r
-\r
- LOGFONT lfCaptionFont;\r
- LOGFONT lfMenuFont;\r
- LOGFONT lfMessageFont;\r
-\r
- HFONT hCaptionFont;\r
- HFONT hMenuFont;\r
- HFONT hMessageFont;\r
-\r
- HMENU hMenu;\r
-\r
-} PREVIEW_DATA, *PPREVIEW_DATA;\r
-\r
-\r
-\r
-static VOID\r
-DrawCaptionButtons(HDC hdc, LPRECT lpRect, BOOL bMinMax)\r
-{\r
- RECT rc3;\r
- RECT rc4;\r
- RECT rc5;\r
-\r
- rc3.left = lpRect->right - 2 - 16;\r
- rc3.top = lpRect->top + 2;\r
- rc3.right = lpRect->right - 2;\r
- rc3.bottom = lpRect->bottom - 2;\r
-\r
- DrawFrameControl(hdc, &rc3, DFC_CAPTION, DFCS_CAPTIONCLOSE);\r
-\r
- if (bMinMax)\r
- {\r
- rc4.left = rc3.left - 16 - 2;\r
- rc4.top = rc3.top;\r
- rc4.right = rc3.right - 16 - 2;\r
- rc4.bottom = rc3.bottom;\r
-\r
- DrawFrameControl(hdc, &rc4, DFC_CAPTION, DFCS_CAPTIONMAX);\r
-\r
- rc5.left = rc4.left - 16;\r
- rc5.top = rc4.top;\r
- rc5.right = rc4.right - 16;\r
- rc5.bottom = rc4.bottom;\r
-\r
- DrawFrameControl(hdc, &rc5, DFC_CAPTION, DFCS_CAPTIONMIN);\r
- }\r
-}\r
-\r
-static VOID\r
-DrawScrollbar(HDC hdc, LPRECT rc, HBRUSH hbrScrollbar)\r
-{\r
- RECT rcTop;\r
- RECT rcBottom;\r
- RECT rcMiddle;\r
- int width;\r
-\r
- width = rc->right - rc->left;\r
-\r
- rcTop.left = rc->left;\r
- rcTop.right = rc->right;\r
- rcTop.top = rc->top;\r
- rcTop.bottom = rc->top + width;\r
-\r
- rcMiddle.left = rc->left;\r
- rcMiddle.right = rc->right;\r
- rcMiddle.top = rc->top + width;\r
- rcMiddle.bottom = rc->bottom - width;\r
-\r
- rcBottom.left = rc->left;\r
- rcBottom.right = rc->right;\r
- rcBottom.top = rc->bottom - width;\r
- rcBottom.bottom = rc->bottom;\r
-\r
- DrawFrameControl(hdc, &rcTop, DFC_SCROLL, DFCS_SCROLLUP);\r
- DrawFrameControl(hdc, &rcBottom, DFC_SCROLL, DFCS_SCROLLDOWN);\r
-\r
- FillRect(hdc, &rcMiddle, hbrScrollbar);\r
-}\r
-\r
-\r
-static VOID\r
-OnCreate(HWND hwnd, PPREVIEW_DATA pPreviewData)\r
-{\r
- NONCLIENTMETRICS NonClientMetrics;\r
-\r
- pPreviewData->clrScrollbar = GetSysColor(COLOR_SCROLLBAR);\r
- pPreviewData->hbrScrollbar = CreateSolidBrush(pPreviewData->clrScrollbar);\r
-\r
- pPreviewData->clrDesktop = GetSysColor(COLOR_DESKTOP);\r
- pPreviewData->hbrDesktop = CreateSolidBrush(pPreviewData->clrDesktop);\r
- pPreviewData->clrWindow = GetSysColor(COLOR_WINDOW);\r
- pPreviewData->hbrWindow = CreateSolidBrush(pPreviewData->clrWindow);\r
-\r
- pPreviewData->clrActiveCaptionText = GetSysColor(COLOR_CAPTIONTEXT);\r
- pPreviewData->clrInactiveCaptionText = GetSysColor(COLOR_INACTIVECAPTIONTEXT);\r
- pPreviewData->clrWindowText = GetSysColor(COLOR_WINDOWTEXT);\r
- pPreviewData->clrButtonText = GetSysColor(COLOR_BTNTEXT);\r
-\r
- pPreviewData->cxEdge = GetSystemMetrics(SM_CXEDGE);\r
- pPreviewData->cyEdge = GetSystemMetrics(SM_CXEDGE);\r
-\r
- pPreviewData->cyCaption = 20; //GetSystemMetrics(SM_CYCAPTION);\r
-\r
- /* load font info */\r
- NonClientMetrics.cbSize = sizeof(NONCLIENTMETRICS);\r
- SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NonClientMetrics, 0);\r
-\r
- pPreviewData->lfCaptionFont = NonClientMetrics.lfCaptionFont;\r
- pPreviewData->hCaptionFont = CreateFontIndirect(&pPreviewData->lfCaptionFont);\r
-\r
- pPreviewData->lfMenuFont = NonClientMetrics.lfMenuFont;\r
- pPreviewData->hMenuFont = CreateFontIndirect(&pPreviewData->lfMenuFont);\r
-\r
- pPreviewData->lfMessageFont = NonClientMetrics.lfMessageFont;\r
- pPreviewData->hMessageFont = CreateFontIndirect(&pPreviewData->lfMessageFont);\r
-\r
- /* Load and modify the menu */\r
- pPreviewData->hMenu = LoadMenu(hApplet, MAKEINTRESOURCE(IDR_PREVIEW_MENU));\r
- EnableMenuItem(pPreviewData->hMenu, ID_MENU_DISABLED,\r
- MF_BYCOMMAND | MF_DISABLED);\r
- HiliteMenuItem(hwnd, pPreviewData->hMenu,\r
- ID_MENU_SELECTED, MF_BYCOMMAND | MF_HILITE);\r
-\r
-// GetMenuItemRect(hwnd, pPreviewData->hMenu,\r
-// ID_MENU_SELECTED, &pPreviewData->rcSelectedMenuItem);\r
-\r
-\r
- AllocAndLoadString(&pPreviewData->lpInAct, hApplet, IDS_INACTWIN);\r
- AllocAndLoadString(&pPreviewData->lpAct, hApplet, IDS_ACTWIN);\r
- AllocAndLoadString(&pPreviewData->lpWinTxt, hApplet, IDS_WINTEXT);\r
- AllocAndLoadString(&pPreviewData->lpMessBox, hApplet, IDS_MESSBOX);\r
- AllocAndLoadString(&pPreviewData->lpMessText, hApplet, IDS_MESSTEXT);\r
- AllocAndLoadString(&pPreviewData->lpButText, hApplet, IDS_BUTTEXT);\r
-}\r
-\r
-\r
-static VOID\r
-OnSize(INT cx, INT cy, PPREVIEW_DATA pPreviewData)\r
-{\r
- int width, height;\r
-\r
- /* Get Desktop rectangle */\r
- pPreviewData->rcDesktop.left = 0;\r
- pPreviewData->rcDesktop.top = 0;\r
- pPreviewData->rcDesktop.right = cx;\r
- pPreviewData->rcDesktop.bottom = cy;\r
-\r
- /* Calculate the inactive window rectangle */\r
- pPreviewData->rcInactiveFrame.left = pPreviewData->rcDesktop.left + 8;\r
- pPreviewData->rcInactiveFrame.top = pPreviewData->rcDesktop.top + 8;\r
- pPreviewData->rcInactiveFrame.right = pPreviewData->rcDesktop.right - 25;\r
- pPreviewData->rcInactiveFrame.bottom = pPreviewData->rcDesktop.bottom - 30;\r
-\r
- /* Calculate the inactive caption rectangle */\r
- pPreviewData->rcInactiveCaption.left = pPreviewData->rcInactiveFrame.left + pPreviewData->cxEdge + 1/*3*/ + 1;\r
- pPreviewData->rcInactiveCaption.top = pPreviewData->rcInactiveFrame.top + pPreviewData->cyEdge + 1/*3*/ + 1;\r
- pPreviewData->rcInactiveCaption.right = pPreviewData->rcInactiveFrame.right - pPreviewData->cxEdge - 1/*3*/ - 1;\r
- pPreviewData->rcInactiveCaption.bottom = pPreviewData->rcInactiveFrame.top + pPreviewData->cyCaption /*20*/ + 2;\r
-\r
- /* Calculate the active window rectangle */\r
- pPreviewData->rcActiveFrame.left = pPreviewData->rcInactiveFrame.left + 3 + 1;\r
- pPreviewData->rcActiveFrame.top = pPreviewData->rcInactiveCaption.bottom + 1;\r
- pPreviewData->rcActiveFrame.right = pPreviewData->rcDesktop.right - 10;\r
- pPreviewData->rcActiveFrame.bottom = pPreviewData->rcDesktop.bottom - 25;\r
-\r
- /* Calculate the active caption rectangle */\r
- pPreviewData->rcActiveCaption.left = pPreviewData->rcActiveFrame.left + 3 + 1;\r
- pPreviewData->rcActiveCaption.top = pPreviewData->rcActiveFrame.top + 3 + 1;\r
- pPreviewData->rcActiveCaption.right = pPreviewData->rcActiveFrame.right - 3 - 1;\r
- pPreviewData->rcActiveCaption.bottom = pPreviewData->rcActiveFrame.top + pPreviewData->cyCaption/*20*/ + 2;\r
-\r
- /* Calculate the active menu bar rectangle */\r
- pPreviewData->rcActiveMenuBar.left = pPreviewData->rcActiveFrame.left + 3 + 1;\r
- pPreviewData->rcActiveMenuBar.top = pPreviewData->rcActiveCaption.bottom + 1;\r
- pPreviewData->rcActiveMenuBar.right = pPreviewData->rcActiveFrame.right - 3 - 1;\r
- pPreviewData->rcActiveMenuBar.bottom = pPreviewData->rcActiveMenuBar.top + 20;\r
-\r
- /* Calculate the active client rectangle */\r
- pPreviewData->rcActiveClient.left = pPreviewData->rcActiveFrame.left + 3 + 1;\r
- pPreviewData->rcActiveClient.top = pPreviewData->rcActiveMenuBar.bottom; // + 1;\r
- pPreviewData->rcActiveClient.right = pPreviewData->rcActiveFrame.right - 3 - 1;\r
- pPreviewData->rcActiveClient.bottom = pPreviewData->rcActiveFrame.bottom - 3 - 1;\r
-\r
- /* Calculate the active scroll rectangle */\r
- pPreviewData->rcActiveScroll.left = pPreviewData->rcActiveClient.right - 2 - 16;\r
- pPreviewData->rcActiveScroll.top = pPreviewData->rcActiveClient.top + 2;\r
- pPreviewData->rcActiveScroll.right = pPreviewData->rcActiveClient.right - 2;\r
- pPreviewData->rcActiveScroll.bottom = pPreviewData->rcActiveClient.bottom - 2;\r
-\r
-\r
- /* Dialog window */\r
- pPreviewData->rcDialogFrame.left = pPreviewData->rcActiveClient.left + 4;\r
- pPreviewData->rcDialogFrame.top = (pPreviewData->rcDesktop.bottom * 60) / 100;\r
- pPreviewData->rcDialogFrame.right = (pPreviewData->rcDesktop.right * 65) / 100;\r
- pPreviewData->rcDialogFrame.bottom = pPreviewData->rcDesktop.bottom - 5;\r
-\r
- /* Calculate the dialog caption rectangle */\r
- pPreviewData->rcDialogCaption.left = pPreviewData->rcDialogFrame.left + 3;\r
- pPreviewData->rcDialogCaption.top = pPreviewData->rcDialogFrame.top + 3;\r
- pPreviewData->rcDialogCaption.right = pPreviewData->rcDialogFrame.right - 3;\r
- pPreviewData->rcDialogCaption.bottom = pPreviewData->rcDialogFrame.top + 20 + 1;\r
-\r
- /* Calculate the dialog client rectangle */\r
- pPreviewData->rcDialogClient.left = pPreviewData->rcDialogFrame.left + 3;\r
- pPreviewData->rcDialogClient.top = pPreviewData->rcDialogCaption.bottom + 1;\r
- pPreviewData->rcDialogClient.right = pPreviewData->rcDialogFrame.right - 3;\r
- pPreviewData->rcDialogClient.bottom = pPreviewData->rcDialogFrame.bottom - 3;\r
-\r
- /* Calculate the dialog button rectangle */\r
- width = 80;\r
- height = 28;\r
-\r
- pPreviewData->rcDialogButton.left =\r
- (pPreviewData->rcDialogClient.right + pPreviewData->rcDialogClient.left - width) / 2;\r
- pPreviewData->rcDialogButton.right = pPreviewData->rcDialogButton.left + width;\r
- pPreviewData->rcDialogButton.bottom = pPreviewData->rcDialogClient.bottom - 2;\r
- pPreviewData->rcDialogButton.top = pPreviewData->rcDialogButton.bottom - height;\r
-}\r
-\r
-\r
-static VOID\r
-OnPaint(HWND hwnd, PPREVIEW_DATA pPreviewData)\r
-{\r
- PAINTSTRUCT ps;\r
- HFONT hOldFont;\r
- HDC hdc;\r
- RECT rc;\r
-\r
- hdc = BeginPaint(hwnd, &ps);\r
-\r
- /* Desktop */\r
- FillRect(hdc, &pPreviewData->rcDesktop, pPreviewData->hbrDesktop);\r
-\r
- /* Inactive Window */\r
- DrawEdge(hdc, &pPreviewData->rcInactiveFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE);\r
- SetTextColor(hdc, pPreviewData->clrInactiveCaptionText);\r
- DrawCaptionTemp(NULL, hdc, &pPreviewData->rcInactiveCaption, pPreviewData->hCaptionFont,\r
- NULL, pPreviewData->lpInAct, DC_GRADIENT | DC_ICON | DC_TEXT);\r
- DrawCaptionButtons(hdc, &pPreviewData->rcInactiveCaption, TRUE);\r
-\r
- /* Active Window */\r
- DrawEdge(hdc, &pPreviewData->rcActiveFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE);\r
- SetTextColor(hdc, pPreviewData->clrActiveCaptionText);\r
- DrawCaptionTemp(NULL, hdc, &pPreviewData->rcActiveCaption, pPreviewData->hCaptionFont,\r
- NULL, pPreviewData->lpAct, DC_ACTIVE | DC_GRADIENT | DC_ICON | DC_TEXT);\r
- DrawCaptionButtons(hdc, &pPreviewData->rcActiveCaption, TRUE);\r
-\r
- /* FIXME: Draw the menu bar */\r
- DrawMenuBarTemp(hwnd, hdc, &pPreviewData->rcActiveMenuBar,\r
- pPreviewData->hMenu /*HMENU hMenu*/,\r
- pPreviewData->hMessageFont /*HFONT hFont*/);\r
-\r
- /* Draw the client area */\r
- CopyRect(&rc, &pPreviewData->rcActiveClient);\r
- DrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_ADJUST);\r
- FillRect(hdc, &rc, pPreviewData->hbrWindow);\r
-\r
- /* Draw the client text */\r
- CopyRect(&rc, &pPreviewData->rcActiveClient);\r
- rc.left += 4;\r
- rc.top += 2;\r
- SetTextColor(hdc, pPreviewData->clrWindowText);\r
- hOldFont = SelectObject(hdc, pPreviewData->hMessageFont);\r
- DrawText(hdc, pPreviewData->lpWinTxt, lstrlen(pPreviewData->lpWinTxt), &rc, DT_LEFT);\r
- SelectObject(hdc, hOldFont);\r
-\r
- /* Draw the scroll bar */\r
- DrawScrollbar(hdc, &pPreviewData->rcActiveScroll, pPreviewData->hbrScrollbar);\r
-\r
- /* Dialog Window */\r
- DrawEdge(hdc, &pPreviewData->rcDialogFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE);\r
- SetTextColor(hdc, pPreviewData->clrActiveCaptionText);\r
- DrawCaptionTemp(NULL, hdc, &pPreviewData->rcDialogCaption, pPreviewData->hCaptionFont,\r
- NULL, pPreviewData->lpMessBox, DC_ACTIVE | DC_GRADIENT | DC_ICON | DC_TEXT);\r
- DrawCaptionButtons(hdc, &pPreviewData->rcDialogCaption, FALSE);\r
-\r
- /* Draw the dialog text */\r
- CopyRect(&rc, &pPreviewData->rcDialogClient);\r
- rc.left += 4;\r
- rc.top += 2;\r
- SetTextColor(hdc, RGB(0,0,0));\r
- hOldFont = SelectObject(hdc, pPreviewData->hMessageFont);\r
- DrawText(hdc, pPreviewData->lpMessText, lstrlen(pPreviewData->lpMessText), &rc, DT_LEFT);\r
- SelectObject(hdc, hOldFont);\r
-\r
- /* Draw Button */\r
- DrawFrameControl(hdc, &pPreviewData->rcDialogButton, DFC_BUTTON, DFCS_BUTTONPUSH);\r
- CopyRect(&rc, &pPreviewData->rcDialogButton);\r
- SetTextColor(hdc, pPreviewData->clrButtonText);\r
- hOldFont = SelectObject(hdc, pPreviewData->hMessageFont);\r
- DrawText(hdc, pPreviewData->lpButText, lstrlen(pPreviewData->lpButText), &rc, DT_VCENTER | DT_CENTER | DT_SINGLELINE);\r
- SelectObject(hdc, hOldFont);\r
-\r
- EndPaint(hwnd, &ps);\r
-}\r
-\r
-\r
-static VOID\r
-OnLButtonDown(HWND hwnd, int xPos, int yPos, PPREVIEW_DATA pPreviewData)\r
-{\r
- UINT type = IDX_DESKTOP;\r
- POINT pt;\r
-\r
- pt.x = xPos;\r
- pt.y = yPos;\r
-\r
- if (PtInRect(&pPreviewData->rcInactiveFrame, pt))\r
- type = IDX_INACTIVE_BORDER;\r
-\r
- if (PtInRect(&pPreviewData->rcInactiveCaption, pt))\r
- type = IDX_INACTIVE_CAPTION;\r
-\r
-\r
- if (PtInRect(&pPreviewData->rcActiveFrame, pt))\r
- type = IDX_ACTIVE_BORDER;\r
-\r
- if (PtInRect(&pPreviewData->rcActiveCaption, pt))\r
- type = IDX_ACTIVE_CAPTION;\r
-\r
- if (PtInRect(&pPreviewData->rcActiveMenuBar, pt))\r
- type = IDX_MENU;\r
-\r
-// if (PtInRect(&pPreviewData->rcSelectedMenuItem, pt))\r
-// type = IDX_SELECTION;\r
-\r
- if (PtInRect(&pPreviewData->rcActiveClient, pt))\r
- type = IDX_WINDOW;\r
-\r
- if (PtInRect(&pPreviewData->rcActiveScroll, pt))\r
- type = IDX_SCROLLBAR;\r
-\r
-\r
- if (PtInRect(&pPreviewData->rcDialogFrame, pt))\r
- type = IDX_DIALOG;\r
-\r
- if (PtInRect(&pPreviewData->rcDialogCaption, pt))\r
- type = IDX_ACTIVE_CAPTION;\r
-\r
- if (PtInRect(&pPreviewData->rcDialogButton, pt))\r
- type = IDX_3D_OBJECTS;\r
-\r
- SendMessage(GetParent(hwnd), WM_USER, 0, type);\r
-}\r
-\r
-\r
-static VOID\r
-OnDestroy(PPREVIEW_DATA pPreviewData)\r
-{\r
- DeleteObject(pPreviewData->hbrScrollbar);\r
- DeleteObject(pPreviewData->hbrDesktop);\r
- DeleteObject(pPreviewData->hbrWindow);\r
-\r
- DeleteObject(pPreviewData->hCaptionFont);\r
- DeleteObject(pPreviewData->hMenuFont);\r
- DeleteObject(pPreviewData->hMessageFont);\r
-\r
- DestroyMenu(pPreviewData->hMenu);\r
-\r
- LocalFree((HLOCAL)pPreviewData->lpInAct);\r
- LocalFree((HLOCAL)pPreviewData->lpAct);\r
- LocalFree((HLOCAL)pPreviewData->lpWinTxt);\r
- LocalFree((HLOCAL)pPreviewData->lpMessBox);\r
- LocalFree((HLOCAL)pPreviewData->lpMessText);\r
- LocalFree((HLOCAL)pPreviewData->lpButText);\r
-}\r
-\r
-\r
-static LRESULT CALLBACK\r
-PreviewWndProc(HWND hwnd,\r
- UINT uMsg,\r
- WPARAM wParam,\r
- LPARAM lParam)\r
-{\r
- PPREVIEW_DATA pPreviewData;\r
-\r
- pPreviewData = (PPREVIEW_DATA)GetWindowLongPtr(hwnd, GWLP_USERDATA);\r
-\r
- switch (uMsg)\r
- {\r
- case WM_CREATE:\r
- pPreviewData = (PPREVIEW_DATA)HeapAlloc(GetProcessHeap(),\r
- HEAP_ZERO_MEMORY,\r
- sizeof(PREVIEW_DATA));\r
- if (!pPreviewData)\r
- return -1;\r
-\r
- SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pPreviewData);\r
- OnCreate(hwnd, pPreviewData);\r
- break;\r
-\r
- case WM_SIZE:\r
- OnSize(LOWORD(lParam), HIWORD(lParam), pPreviewData);\r
- break;\r
-\r
- case WM_PAINT:\r
- OnPaint(hwnd, pPreviewData);\r
- break;\r
-\r
- case WM_LBUTTONDOWN:\r
- OnLButtonDown(hwnd, LOWORD(lParam), HIWORD(lParam), pPreviewData);\r
- break;\r
-\r
- case WM_DESTROY:\r
- OnDestroy(pPreviewData);\r
- HeapFree(GetProcessHeap(), 0, pPreviewData);\r
- break;\r
-\r
- default:\r
- DefWindowProc(hwnd,\r
- uMsg,\r
- wParam,\r
- lParam);\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-BOOL\r
-RegisterPreviewControl(IN HINSTANCE hInstance)\r
-{\r
- WNDCLASSEX wc = {0};\r
-\r
- wc.cbSize = sizeof(WNDCLASSEX);\r
- wc.lpfnWndProc = PreviewWndProc;\r
- wc.hInstance = hInstance;\r
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);\r
- wc.hbrBackground = (HBRUSH)NULL; //(COLOR_BTNFACE + 1);\r
- wc.lpszClassName = szPreviewWndClass;\r
-\r
- return RegisterClassEx(&wc) != (ATOM)0;\r
-}\r
-\r
-\r
-VOID\r
-UnregisterPreviewControl(IN HINSTANCE hInstance)\r
-{\r
- UnregisterClass(szPreviewWndClass,\r
- hInstance);\r
-}\r
+/*
+ * PROJECT: ReactOS Desktop Control Panel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: lib/cpl/desk/preview.c
+ * PURPOSE: Draws the preview control
+ * COPYRIGHT: Copyright 2006, 2007 Eric Kohl
+ */
+
+#include "desk.h"
+#include "theme.h"
+#include "preview.h"
+#include "draw.h"
+
+static const TCHAR szPreviewWndClass[] = TEXT("PreviewWndClass");
+
+typedef struct _PREVIEW_DATA
+{
+ HWND hwndParent;
+
+ THEME Theme;
+
+ HBRUSH hbrScrollbar;
+ HBRUSH hbrDesktop;
+ HBRUSH hbrWindow;
+
+ INT cxEdge;
+ INT cyEdge;
+
+ INT cySizeFrame;
+
+ INT cyCaption;
+ INT cyBorder;
+ INT cyMenu;
+ INT cxScrollbar;
+
+ RECT rcDesktop;
+ RECT rcInactiveFrame;
+ RECT rcInactiveCaption;
+ RECT rcInactiveCaptionButtons;
+
+ RECT rcActiveFrame;
+ RECT rcActiveCaption;
+ RECT rcActiveCaptionButtons;
+ RECT rcActiveMenuBar;
+ RECT rcSelectedMenuItem;
+ RECT rcActiveClient;
+ RECT rcActiveScroll;
+
+ RECT rcDialogFrame;
+ RECT rcDialogCaption;
+ RECT rcDialogCaptionButtons;
+ RECT rcDialogClient;
+
+ RECT rcDialogButton;
+
+ LPTSTR lpInAct;
+ LPTSTR lpAct;
+ LPTSTR lpWinTxt;
+ LPTSTR lpMessBox;
+ LPTSTR lpMessText;
+ LPTSTR lpButText;
+
+ HFONT hCaptionFont;
+ HFONT hMenuFont;
+ HFONT hMessageFont;
+ HFONT hClientFont;
+
+ HMENU hMenu;
+
+} PREVIEW_DATA, *PPREVIEW_DATA;
+
+
+static VOID UpdatePreviewTheme(HWND hwnd, PPREVIEW_DATA pPreviewData, THEME *theme)
+{
+ if (pPreviewData->hbrScrollbar != NULL)
+ DeleteObject(pPreviewData->hbrScrollbar);
+ pPreviewData->hbrScrollbar = CreateSolidBrush(theme->crColor[COLOR_SCROLLBAR]);
+ if (pPreviewData->hbrDesktop != NULL)
+ DeleteObject(pPreviewData->hbrDesktop);
+ pPreviewData->hbrDesktop = CreateSolidBrush(theme->crColor[COLOR_DESKTOP]);
+ if (pPreviewData->hbrWindow != NULL)
+ DeleteObject(pPreviewData->hbrWindow);
+ pPreviewData->hbrWindow = CreateSolidBrush(theme->crColor[COLOR_WINDOW]);
+
+ pPreviewData->cxEdge = theme->Size[SIZE_EDGE_X] - 2; /* SM_CXEDGE */
+ pPreviewData->cyEdge = theme->Size[SIZE_EDGE_Y] - 2; /* SM_CYEDGE */
+
+ pPreviewData->cySizeFrame = theme->Size[SIZE_FRAME_Y] - 1; /* SM_CYSIZEFRAME */
+
+ pPreviewData->cyCaption = theme->Size[SIZE_CAPTION_Y]; /* SM_CYCAPTION */
+ pPreviewData->cyMenu = theme->Size[SIZE_MENU_Y]; /* SM_CYMENU */
+ pPreviewData->cxScrollbar = theme->Size[SIZE_SCROLL_X]; /* SM_CXVSCROLL */
+ pPreviewData->cyBorder = theme->Size[SIZE_BORDER_Y]; /* SM_CYBORDER */
+
+ if (pPreviewData->hCaptionFont != NULL)
+ DeleteObject(pPreviewData->hCaptionFont);
+ pPreviewData->hCaptionFont = CreateFontIndirect(&theme->lfFont[FONT_CAPTION]);
+
+ if (pPreviewData->hMenuFont != NULL)
+ DeleteObject(pPreviewData->hMenuFont);
+ pPreviewData->hMenuFont = CreateFontIndirect(&theme->lfFont[FONT_MENU]);
+
+ if (pPreviewData->hMessageFont != NULL)
+ DeleteObject(pPreviewData->hMessageFont);
+ pPreviewData->hMessageFont = CreateFontIndirect(&theme->lfFont[FONT_DIALOG]);
+
+ pPreviewData->Theme = *theme;
+ InvalidateRect(hwnd, NULL, FALSE);
+}
+
+static VOID
+OnCreate(HWND hwnd, PPREVIEW_DATA pPreviewData)
+{
+ THEME *theme;
+
+ pPreviewData->hClientFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+
+ /* Load and modify the menu */
+ pPreviewData->hMenu = LoadMenu(hApplet, MAKEINTRESOURCE(IDR_PREVIEW_MENU));
+ EnableMenuItem(pPreviewData->hMenu,
+ 1, MF_BYPOSITION | MF_GRAYED);
+ HiliteMenuItem(hwnd, pPreviewData->hMenu,
+ 2, MF_BYPOSITION | MF_HILITE);
+
+// GetMenuItemRect(hwnd, pPreviewData->hMenu,
+// 2, &pPreviewData->rcSelectedMenuItem);
+
+ AllocAndLoadString(&pPreviewData->lpInAct, hApplet, IDS_INACTWIN);
+ AllocAndLoadString(&pPreviewData->lpAct, hApplet, IDS_ACTWIN);
+ AllocAndLoadString(&pPreviewData->lpWinTxt, hApplet, IDS_WINTEXT);
+ AllocAndLoadString(&pPreviewData->lpMessBox, hApplet, IDS_MESSBOX);
+ AllocAndLoadString(&pPreviewData->lpMessText, hApplet, IDS_MESSTEXT);
+ AllocAndLoadString(&pPreviewData->lpButText, hApplet, IDS_BUTTEXT);
+
+ theme = &pPreviewData->Theme;
+ LoadCurrentTheme(theme);
+
+ UpdatePreviewTheme(hwnd, pPreviewData, theme);
+}
+
+
+static VOID
+CalculateItemSize(PPREVIEW_DATA pPreviewData)
+{
+ int width, height;
+
+ /* Calculate the inactive window rectangle */
+ pPreviewData->rcInactiveFrame.left = pPreviewData->rcDesktop.left + 8;
+ pPreviewData->rcInactiveFrame.top = pPreviewData->rcDesktop.top + 8;
+ pPreviewData->rcInactiveFrame.right = pPreviewData->rcDesktop.right - 25;
+ pPreviewData->rcInactiveFrame.bottom = pPreviewData->rcDesktop.bottom - 30;
+
+ /* Calculate the inactive caption rectangle */
+ pPreviewData->rcInactiveCaption.left = pPreviewData->rcInactiveFrame.left + pPreviewData->cxEdge + pPreviewData->cySizeFrame + 1;
+ pPreviewData->rcInactiveCaption.top = pPreviewData->rcInactiveFrame.top + pPreviewData->cyEdge + pPreviewData->cySizeFrame + 1;
+ pPreviewData->rcInactiveCaption.right = pPreviewData->rcInactiveFrame.right - pPreviewData->cxEdge - pPreviewData->cySizeFrame - 1;
+ pPreviewData->rcInactiveCaption.bottom = pPreviewData->rcInactiveCaption.top + pPreviewData->cyCaption - pPreviewData->cyBorder;
+
+ /* Calculate the inactive caption buttons rectangle */
+ pPreviewData->rcInactiveCaptionButtons.left = pPreviewData->rcInactiveCaption.right - 2 - 2 - 3 * 16;
+ pPreviewData->rcInactiveCaptionButtons.top = pPreviewData->rcInactiveCaption.top + 2;
+ pPreviewData->rcInactiveCaptionButtons.right = pPreviewData->rcInactiveCaption.right - 2;
+ pPreviewData->rcInactiveCaptionButtons.bottom = pPreviewData->rcInactiveCaption.bottom - 2;
+
+ /* Calculate the active window rectangle */
+ pPreviewData->rcActiveFrame.left = pPreviewData->rcInactiveFrame.left + 3 + pPreviewData->cySizeFrame;
+ pPreviewData->rcActiveFrame.top = pPreviewData->rcInactiveCaption.bottom + 1;
+ pPreviewData->rcActiveFrame.right = pPreviewData->rcDesktop.right - 10;
+ pPreviewData->rcActiveFrame.bottom = pPreviewData->rcDesktop.bottom - 25;
+
+ /* Calculate the active caption rectangle */
+ pPreviewData->rcActiveCaption.left = pPreviewData->rcActiveFrame.left + pPreviewData->cxEdge + pPreviewData->cySizeFrame + 1;
+ pPreviewData->rcActiveCaption.top = pPreviewData->rcActiveFrame.top + pPreviewData->cxEdge + pPreviewData->cySizeFrame + 1;
+ pPreviewData->rcActiveCaption.right = pPreviewData->rcActiveFrame.right - pPreviewData->cxEdge - pPreviewData->cySizeFrame - 1;
+ pPreviewData->rcActiveCaption.bottom = pPreviewData->rcActiveCaption.top + pPreviewData->cyCaption - pPreviewData->cyBorder;
+
+ /* Calculate the active caption buttons rectangle */
+ pPreviewData->rcActiveCaptionButtons.left = pPreviewData->rcActiveCaption.right - 2 - 2 - 3 * 16;
+ pPreviewData->rcActiveCaptionButtons.top = pPreviewData->rcActiveCaption.top + 2;
+ pPreviewData->rcActiveCaptionButtons.right = pPreviewData->rcActiveCaption.right - 2;
+ pPreviewData->rcActiveCaptionButtons.bottom = pPreviewData->rcActiveCaption.bottom - 2;
+
+ /* Calculate the active menu bar rectangle */
+ pPreviewData->rcActiveMenuBar.left = pPreviewData->rcActiveFrame.left + pPreviewData->cxEdge + pPreviewData->cySizeFrame + 1;
+ pPreviewData->rcActiveMenuBar.top = pPreviewData->rcActiveCaption.bottom + 1;
+ pPreviewData->rcActiveMenuBar.right = pPreviewData->rcActiveFrame.right - pPreviewData->cxEdge - pPreviewData->cySizeFrame - 1;
+ pPreviewData->rcActiveMenuBar.bottom = pPreviewData->rcActiveMenuBar.top + pPreviewData->cyMenu + 1;
+
+ /* Calculate the active client rectangle */
+ pPreviewData->rcActiveClient.left = pPreviewData->rcActiveFrame.left + pPreviewData->cxEdge + pPreviewData->cySizeFrame + 1;
+ pPreviewData->rcActiveClient.top = pPreviewData->rcActiveMenuBar.bottom;
+ pPreviewData->rcActiveClient.right = pPreviewData->rcActiveFrame.right - pPreviewData->cxEdge - pPreviewData->cySizeFrame - 1;
+ pPreviewData->rcActiveClient.bottom = pPreviewData->rcActiveFrame.bottom - pPreviewData->cyEdge - pPreviewData->cySizeFrame - 1;
+
+ /* Calculate the active scroll rectangle */
+ pPreviewData->rcActiveScroll.left = pPreviewData->rcActiveClient.right - 2 - pPreviewData->cxScrollbar;
+ pPreviewData->rcActiveScroll.top = pPreviewData->rcActiveClient.top + 2;
+ pPreviewData->rcActiveScroll.right = pPreviewData->rcActiveClient.right - 2;
+ pPreviewData->rcActiveScroll.bottom = pPreviewData->rcActiveClient.bottom - 2;
+
+
+ /* Dialog window */
+ pPreviewData->rcDialogFrame.left = pPreviewData->rcActiveClient.left + 4;
+ pPreviewData->rcDialogFrame.top = (pPreviewData->rcDesktop.bottom * 60) / 100;
+ pPreviewData->rcDialogFrame.right = (pPreviewData->rcDesktop.right * 65) / 100;
+ pPreviewData->rcDialogFrame.bottom = pPreviewData->rcDesktop.bottom - 5;
+
+ /* Calculate the dialog caption rectangle */
+ pPreviewData->rcDialogCaption.left = pPreviewData->rcDialogFrame.left + 3;
+ pPreviewData->rcDialogCaption.top = pPreviewData->rcDialogFrame.top + 3;
+ pPreviewData->rcDialogCaption.right = pPreviewData->rcDialogFrame.right - 3;
+ pPreviewData->rcDialogCaption.bottom = pPreviewData->rcDialogFrame.top + pPreviewData->cyCaption + 1 + 1;
+
+ /* Calculate the inactive caption buttons rectangle */
+ pPreviewData->rcDialogCaptionButtons.left = pPreviewData->rcDialogCaption.right - 2 - 16;
+ pPreviewData->rcDialogCaptionButtons.top = pPreviewData->rcDialogCaption.top + 2;
+ pPreviewData->rcDialogCaptionButtons.right = pPreviewData->rcDialogCaption.right - 2;
+ pPreviewData->rcDialogCaptionButtons.bottom = pPreviewData->rcDialogCaption.bottom - 2;
+
+ /* Calculate the dialog client rectangle */
+ pPreviewData->rcDialogClient.left = pPreviewData->rcDialogFrame.left + 3;
+ pPreviewData->rcDialogClient.top = pPreviewData->rcDialogCaption.bottom + 1;
+ pPreviewData->rcDialogClient.right = pPreviewData->rcDialogFrame.right - 3;
+ pPreviewData->rcDialogClient.bottom = pPreviewData->rcDialogFrame.bottom - 3;
+
+ /* Calculate the dialog button rectangle */
+ width = 80;
+ height = 28;
+
+ pPreviewData->rcDialogButton.left =
+ (pPreviewData->rcDialogClient.right + pPreviewData->rcDialogClient.left - width) / 2;
+ pPreviewData->rcDialogButton.right = pPreviewData->rcDialogButton.left + width;
+ pPreviewData->rcDialogButton.bottom = pPreviewData->rcDialogClient.bottom - 2;
+ pPreviewData->rcDialogButton.top = pPreviewData->rcDialogButton.bottom - height;
+}
+
+
+static VOID
+OnSize(INT cx, INT cy, PPREVIEW_DATA pPreviewData)
+{
+ /* Get Desktop rectangle */
+ pPreviewData->rcDesktop.left = 0;
+ pPreviewData->rcDesktop.top = 0;
+ pPreviewData->rcDesktop.right = cx;
+ pPreviewData->rcDesktop.bottom = cy;
+
+ CalculateItemSize(pPreviewData);
+}
+
+static VOID
+OnPaint(HWND hwnd, PPREVIEW_DATA pPreviewData)
+{
+ PAINTSTRUCT ps;
+ HFONT hOldFont;
+ HDC hdc;
+ RECT rc;
+ THEME *theme;
+
+ theme = &pPreviewData->Theme;
+
+ hdc = BeginPaint(hwnd, &ps);
+
+ /* Desktop */
+ FillRect(hdc, &pPreviewData->rcDesktop, pPreviewData->hbrDesktop);
+
+ /* Inactive Window */
+ MyDrawEdge(hdc, &pPreviewData->rcInactiveFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE, theme);
+ SetTextColor(hdc, theme->crColor[COLOR_INACTIVECAPTIONTEXT]);
+ MyDrawCaptionTemp(NULL, hdc, &pPreviewData->rcInactiveCaption, pPreviewData->hCaptionFont,
+ NULL, pPreviewData->lpInAct, DC_GRADIENT | DC_ICON | DC_TEXT, theme);
+ MyDrawCaptionButtons(hdc, &pPreviewData->rcInactiveCaption, TRUE, pPreviewData->cyCaption - 2, theme);
+
+ /* Active Window */
+ MyDrawEdge(hdc, &pPreviewData->rcActiveFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE, theme);
+ SetTextColor(hdc, theme->crColor[COLOR_CAPTIONTEXT]);
+ MyDrawCaptionTemp(NULL, hdc, &pPreviewData->rcActiveCaption, pPreviewData->hCaptionFont,
+ NULL, pPreviewData->lpAct, DC_ACTIVE | DC_GRADIENT | DC_ICON | DC_TEXT, theme);
+ MyDrawCaptionButtons(hdc, &pPreviewData->rcActiveCaption, TRUE, pPreviewData->cyCaption - 2, theme);
+
+ /* Draw the menu bar */
+ MyDrawMenuBarTemp(hwnd, hdc, &pPreviewData->rcActiveMenuBar,
+ pPreviewData->hMenu,
+ pPreviewData->hMenuFont, theme);
+
+ /* Draw the client area */
+ CopyRect(&rc, &pPreviewData->rcActiveClient);
+ MyDrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_ADJUST, theme);
+ FillRect(hdc, &rc, pPreviewData->hbrWindow);
+
+ /* Draw the client text */
+ CopyRect(&rc, &pPreviewData->rcActiveClient);
+ rc.left += 4;
+ rc.top += 2;
+ SetTextColor(hdc, theme->crColor[COLOR_WINDOWTEXT]);
+ hOldFont = SelectObject(hdc, pPreviewData->hClientFont);
+ DrawText(hdc, pPreviewData->lpWinTxt, -1, &rc, DT_LEFT);
+ SelectObject(hdc, hOldFont);
+
+ /* Draw the scroll bar */
+ MyDrawScrollbar(hdc, &pPreviewData->rcActiveScroll, pPreviewData->hbrScrollbar, theme);
+
+ /* Dialog Window */
+ MyDrawEdge(hdc, &pPreviewData->rcDialogFrame, EDGE_RAISED, BF_RECT | BF_MIDDLE, theme);
+ SetTextColor(hdc, theme->crColor[COLOR_WINDOW]);
+ MyDrawCaptionTemp(NULL, hdc, &pPreviewData->rcDialogCaption, pPreviewData->hCaptionFont,
+ NULL, pPreviewData->lpMessBox, DC_ACTIVE | DC_GRADIENT | DC_ICON | DC_TEXT, theme);
+ MyDrawCaptionButtons(hdc, &pPreviewData->rcDialogCaption, FALSE, pPreviewData->cyCaption - 2, theme);
+
+ /* Draw the dialog text */
+ CopyRect(&rc, &pPreviewData->rcDialogClient);
+ rc.left += 4;
+ rc.top += 2;
+ SetTextColor(hdc, theme->crColor[COLOR_BTNTEXT]);
+ hOldFont = SelectObject(hdc, pPreviewData->hMessageFont);
+ DrawText(hdc, pPreviewData->lpMessText, -1, &rc, DT_LEFT);
+ SelectObject(hdc, hOldFont);
+
+ /* Draw Button */
+ MyDrawFrameControl(hdc, &pPreviewData->rcDialogButton, DFC_BUTTON, DFCS_BUTTONPUSH, theme);
+ CopyRect(&rc, &pPreviewData->rcDialogButton);
+ SetTextColor(hdc, theme->crColor[COLOR_BTNTEXT]);
+ hOldFont = SelectObject(hdc, pPreviewData->hMessageFont);
+ DrawText(hdc, pPreviewData->lpButText, -1, &rc, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
+ SelectObject(hdc, hOldFont);
+
+ EndPaint(hwnd, &ps);
+}
+
+
+static VOID
+OnLButtonDown(HWND hwnd, int xPos, int yPos, PPREVIEW_DATA pPreviewData)
+{
+ UINT type = IDX_DESKTOP;
+ POINT pt;
+
+ pt.x = xPos;
+ pt.y = yPos;
+
+ if (PtInRect(&pPreviewData->rcInactiveFrame, pt))
+ type = IDX_INACTIVE_BORDER;
+
+ if (PtInRect(&pPreviewData->rcInactiveCaption, pt))
+ type = IDX_INACTIVE_CAPTION;
+
+ if (PtInRect(&pPreviewData->rcInactiveCaptionButtons, pt))
+ type = IDX_CAPTION_BUTTON;
+
+ if (PtInRect(&pPreviewData->rcActiveFrame, pt))
+ type = IDX_ACTIVE_BORDER;
+
+ if (PtInRect(&pPreviewData->rcActiveCaption, pt))
+ type = IDX_ACTIVE_CAPTION;
+
+ if (PtInRect(&pPreviewData->rcActiveCaptionButtons, pt))
+ type = IDX_CAPTION_BUTTON;
+
+// if (PtInRect(&pPreviewData->rcSelectedMenuItem, pt))
+// type = IDX_SELECTION;
+
+ if (PtInRect(&pPreviewData->rcActiveMenuBar, pt))
+ type = IDX_MENU;
+
+ if (PtInRect(&pPreviewData->rcActiveClient, pt))
+ type = IDX_WINDOW;
+
+ if (PtInRect(&pPreviewData->rcActiveScroll, pt))
+ type = IDX_SCROLLBAR;
+
+ if (PtInRect(&pPreviewData->rcDialogFrame, pt))
+ type = IDX_DIALOG;
+
+ if (PtInRect(&pPreviewData->rcDialogCaption, pt))
+ type = IDX_ACTIVE_CAPTION;
+
+ if (PtInRect(&pPreviewData->rcDialogCaptionButtons, pt))
+ type = IDX_CAPTION_BUTTON;
+
+ if (PtInRect(&pPreviewData->rcDialogButton, pt))
+ type = IDX_3D_OBJECTS;
+
+ SendMessage(GetParent(hwnd),
+ WM_COMMAND,
+ MAKEWPARAM(GetWindowLongPtrW(hwnd, GWLP_ID), 0),
+ (LPARAM)type);
+}
+
+
+static VOID
+OnDestroy(PPREVIEW_DATA pPreviewData)
+{
+ DeleteObject(pPreviewData->hbrScrollbar);
+ DeleteObject(pPreviewData->hbrDesktop);
+ DeleteObject(pPreviewData->hbrWindow);
+
+ DeleteObject(pPreviewData->hCaptionFont);
+ DeleteObject(pPreviewData->hMenuFont);
+ DeleteObject(pPreviewData->hMessageFont);
+
+ DestroyMenu(pPreviewData->hMenu);
+
+ LocalFree((HLOCAL)pPreviewData->lpInAct);
+ LocalFree((HLOCAL)pPreviewData->lpAct);
+ LocalFree((HLOCAL)pPreviewData->lpWinTxt);
+ LocalFree((HLOCAL)pPreviewData->lpMessBox);
+ LocalFree((HLOCAL)pPreviewData->lpMessText);
+ LocalFree((HLOCAL)pPreviewData->lpButText);
+}
+
+
+static LRESULT CALLBACK
+PreviewWndProc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ PPREVIEW_DATA pPreviewData;
+
+ pPreviewData = (PPREVIEW_DATA)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+
+ switch (uMsg)
+ {
+ case WM_CREATE:
+ pPreviewData = (PPREVIEW_DATA)HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(PREVIEW_DATA));
+ if (!pPreviewData)
+ return -1;
+
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pPreviewData);
+ OnCreate(hwnd, pPreviewData);
+ break;
+
+ case WM_SIZE:
+ OnSize(LOWORD(lParam), HIWORD(lParam), pPreviewData);
+ break;
+
+ case WM_PAINT:
+ OnPaint(hwnd, pPreviewData);
+ break;
+
+ case WM_LBUTTONDOWN:
+ OnLButtonDown(hwnd, LOWORD(lParam), HIWORD(lParam), pPreviewData);
+ break;
+
+ case WM_DESTROY:
+ OnDestroy(pPreviewData);
+ HeapFree(GetProcessHeap(), 0, pPreviewData);
+ break;
+
+ case PVM_GETCYCAPTION:
+ return pPreviewData->cyCaption;
+
+ case PVM_SETCYCAPTION:
+ if ((INT)lParam > 0)
+ {
+ pPreviewData->cyCaption = (INT)lParam;
+ CalculateItemSize(pPreviewData);
+ InvalidateRect(hwnd, NULL, FALSE);
+ }
+ break;
+
+ case PVM_GETCYMENU:
+ return pPreviewData->cyMenu;
+
+ case PVM_SETCYMENU:
+ if ((INT)lParam > 0)
+ {
+ pPreviewData->cyMenu = (INT)lParam;
+ CalculateItemSize(pPreviewData);
+ InvalidateRect(hwnd, NULL, FALSE);
+ }
+ break;
+
+ case PVM_GETCXSCROLLBAR:
+ return pPreviewData->cxScrollbar;
+
+ case PVM_SETCXSCROLLBAR:
+ if ((INT)lParam > 0)
+ {
+ pPreviewData->cxScrollbar = (INT)lParam;
+ CalculateItemSize(pPreviewData);
+ InvalidateRect(hwnd, NULL, FALSE);
+ }
+ break;
+
+ case PVM_GETCYSIZEFRAME:
+ return pPreviewData->cySizeFrame;
+
+ case PVM_SETCYSIZEFRAME:
+ if ((INT)lParam > 0)
+ {
+ pPreviewData->cySizeFrame = (INT)lParam;
+ CalculateItemSize(pPreviewData);
+ InvalidateRect(hwnd, NULL, FALSE);
+ }
+ break;
+
+ case PVM_UPDATETHEME:
+ UpdatePreviewTheme(hwnd, pPreviewData, (THEME *)lParam);
+ break;
+
+ default:
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
+ }
+ return FALSE;
+}
+
+
+BOOL
+RegisterPreviewControl(IN HINSTANCE hInstance)
+{
+ WNDCLASSEX wc = {0};
+
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.lpfnWndProc = PreviewWndProc;
+ wc.hInstance = hInstance;
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)NULL;
+ wc.lpszClassName = szPreviewWndClass;
+
+ return RegisterClassEx(&wc) != (ATOM)0;
+}
+
+
+VOID
+UnregisterPreviewControl(IN HINSTANCE hInstance)
+{
+ UnregisterClass(szPreviewWndClass, hInstance);
+}