windows-nt/Source/XPSP1/NT/shell/themes/themeui/dragsize.cpp
2020-09-26 16:20:57 +08:00

291 lines
6.6 KiB
C++

/*
** DRAGSIZE.C
**
** Drag size bar code
**
*/
#include "priv.h"
#pragma hdrstop
typedef struct tagDRAGSIZEINFO
{
DWORD_PTR lpData;
BOOL bDragging;
POINT ptNow;
HFONT hFont;
} DRAGSIZEINFO, *PDRAGSIZEINFO;
static TCHAR szDragSizeClass[] = DRAGSIZECLASSNAME;
LRESULT NEAR PASCAL InitDragSizeWnd(HWND hWnd, LPCREATESTRUCT lpCreate)
{
PDRAGSIZEINFO pDragSizeInfo;
/* Create the status info struct; abort if it does not exist,
** otherwise save it in the window structure
*/
pDragSizeInfo = ALLOCWINDOWPOINTER(PDRAGSIZEINFO, sizeof(DRAGSIZEINFO));
if (!pDragSizeInfo)
{
return(-1);
}
SETWINDOWPOINTER(hWnd, PDRAGSIZEINFO, pDragSizeInfo);
pDragSizeInfo->lpData = (DWORD_PTR)lpCreate->lpCreateParams;
pDragSizeInfo->bDragging = FALSE;
return(0);
}
/* Track the mouse and send messages to the parent whenever it moves.
*/
void NEAR PASCAL DragSize(HWND hWnd, PDRAGSIZEINFO pDragSizeInfo, POINT ptStart)
{
MSG msg;
HWND hwndParent;
LONG wID;
if (!pDragSizeInfo || pDragSizeInfo->bDragging)
{
return;
}
pDragSizeInfo->bDragging = TRUE;
pDragSizeInfo->ptNow = ptStart;
SetCapture(hWnd);
hwndParent = GetParent(hWnd);
wID = GETWINDOWID(hWnd);
SendMessage(hwndParent, WM_COMMAND, MAKEWPARAM(wID, DSN_BEGINDRAG), (LPARAM)hWnd);
for ( ; ; )
{
if (GetCapture() != hWnd)
{
EndAbort:
/* Abort the process.
*/
pDragSizeInfo->ptNow = ptStart;
SendMessage(hwndParent, WM_COMMAND, MAKEWPARAM(wID, DSN_DRAGGING), (LPARAM)hWnd);
goto EndAdjust;
}
if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
continue;
}
switch (msg.message)
{
case WM_KEYDOWN:
switch (msg.wParam)
{
case VK_ESCAPE:
AbortAdjust:
SetCapture(NULL);
goto EndAbort;
default:
break;
}
break;
case WM_KEYUP:
case WM_CHAR:
break;
case WM_LBUTTONDOWN:
/* This shouldn't happen.
*/
goto AbortAdjust;
case WM_MOUSEMOVE:
LPARAM2POINT( msg.lParam, &(pDragSizeInfo->ptNow) );
TraceMsg(TF_GENERAL, "DragSize: ptNow = (%d, %d)\n", pDragSizeInfo->ptNow.x, pDragSizeInfo->ptNow.y);
SendMessage(hwndParent, WM_COMMAND, MAKEWPARAM(wID, DSN_DRAGGING), (LPARAM)hWnd);
break;
case WM_LBUTTONUP:
/* All done.
*/
SetCapture(NULL);
goto EndAdjust;
case WM_RBUTTONDOWN:
goto AbortAdjust;
default:
TranslateMessage(&msg);
DispatchMessage(&msg);
break;
}
}
EndAdjust:
SendMessage(hwndParent, WM_COMMAND, MAKEWPARAM(wID, DSN_ENDDRAG), (LPARAM)hWnd);
pDragSizeInfo->bDragging = FALSE;
}
/* Ask the parent to paint the window.
*/
void NEAR PASCAL PaintDragSizeWnd(HWND hWnd, PDRAGSIZEINFO pDragSizeInfo)
{
PAINTSTRUCT ps;
DRAWITEMSTRUCT dis;
HDC hDC;
HFONT hOldFont = NULL;
if (!pDragSizeInfo)
{
return;
}
hDC = BeginPaint(hWnd, &ps);
if (pDragSizeInfo->hFont)
{
hOldFont = (HFONT) SelectObject(hDC, pDragSizeInfo->hFont);
}
/* Fill in the DRAWITEMSTRUCT. Note that some of the fields are
** undefined.
*/
dis.CtlID = GetDlgCtrlID(hWnd);
dis.hwndItem = hWnd;
dis.hDC = hDC;
GetClientRect(hWnd, &dis.rcItem);
dis.itemData = pDragSizeInfo->lpData;
SendMessage(GetParent(hWnd), WM_DRAWITEM, GetDlgCtrlID(hWnd),
(LPARAM)(LPDRAWITEMSTRUCT)&dis);
if (hOldFont)
{
SelectObject(hDC, hOldFont);
}
EndPaint(hWnd, &ps);
}
LRESULT CALLBACK DragSizeWndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
#define lpCreate ((LPCREATESTRUCT)lParam)
PDRAGSIZEINFO pDragSizeInfo;
pDragSizeInfo = GETWINDOWPOINTER(hWnd, PDRAGSIZEINFO);
switch (uMessage)
{
case WM_NCCREATE:
SendMessage(lpCreate->hwndParent, WM_COMMAND,
MAKEWPARAM((SHORT)(lpCreate->hMenu), DSN_NCCREATE), (LPARAM)hWnd);
break;
case WM_CREATE:
InitDragSizeWnd(hWnd, (LPCREATESTRUCT)lParam);
break;
case WM_DESTROY:
if (pDragSizeInfo)
{
FREEWINDOWPOINTER(pDragSizeInfo);
SETWINDOWPOINTER(hWnd, PDRAGSIZEINFO, NULL);
}
break;
case WM_LBUTTONDOWN: {
POINT pt;
LPARAM2POINT( lParam, &pt );
DragSize(hWnd, pDragSizeInfo, pt);
}
break;
case WM_PAINT:
PaintDragSizeWnd(hWnd, pDragSizeInfo);
return(0);
case WM_SETFONT:
if (!pDragSizeInfo)
{
return(1L);
}
pDragSizeInfo->hFont = (HFONT)wParam;
if (LOWORD(lParam))
{
InvalidateRect(hWnd, NULL, TRUE);
UpdateWindow(hWnd);
}
return(0L);
case WM_GETFONT:
if (!pDragSizeInfo)
{
return(LRESULT)(NULL);
}
return(MAKELRESULT(pDragSizeInfo->hFont, 0));
case DSM_DRAGPOS: {
LPPOINT lppt = (LPPOINT)lParam;
if (!pDragSizeInfo || !pDragSizeInfo->bDragging || lppt == NULL)
{
return(-1L);
}
*lppt = pDragSizeInfo->ptNow;
return(0);
}
break;
default:
break;
}
return(DefWindowProc(hWnd, uMessage, wParam, lParam));
}
BOOL FAR PASCAL InitDragSizeClass(void)
{
WNDCLASS rClass;
if (GetClassInfo(HINST_THISDLL, szDragSizeClass, &rClass))
{
return(TRUE);
}
rClass.style = 0;
rClass.lpfnWndProc = DragSizeWndProc;
rClass.cbClsExtra = 0;
rClass.cbWndExtra = sizeof(PDRAGSIZEINFO);
rClass.hInstance = HINST_THISDLL;
rClass.hIcon = NULL;
rClass.hCursor = LoadCursor(NULL, IDC_ARROW);
rClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
rClass.lpszMenuName = NULL;
rClass.lpszClassName = szDragSizeClass;
return(RegisterClass(&rClass));
}
HWND WINAPI CreateDragSizeWindow(LONG style, int x, int y, int wid, int hgt, HWND hwndParent, LONG wID)
{
/* Create a default window and return
*/
return(CreateWindow(szDragSizeClass, g_szNULL, style,
x, y, wid, hgt, hwndParent, (HMENU)IntToPtr(wID), HINST_THISDLL, NULL));
}