📄 durationcontrol.c
字号:
/*____________________________________________________________________________
Copyright (C) 1998 Network Associates, Inc.
All rights reserved.
DurationControl.c - PGPnet duration custom control
$Id: DurationControl.c,v 1.7 1999/04/01 14:53:54 pbj Exp $
____________________________________________________________________________*/
#include <windows.h>
#include <commctrl.h>
#include "DurationControl.h"
#define MAXTEXTLEN 8
// Duration control window extra data. Must include window handle field.
typedef struct _DCWndData {
HWND hwnd;
HWND hwndParent;
INT iID;
DWORD dwStyle;
HWND hwndEdit[NUM_FIELDS];
WNDPROC wpOrigEditProc[NUM_FIELDS];
UINT uValue[NUM_FIELDS];
INT iRangeLo[NUM_FIELDS];
INT iRangeHi[NUM_FIELDS];
CHAR szText[NUM_FIELDS][MAXTEXTLEN];
HWND hwndText[NUM_FIELDS];
WNDPROC wpOrigTextProc[NUM_FIELDS];
HWND hwndUpDown;
HFONT hFont;
INT iFocused;
INT iPrevFocused;
BOOL bFirstKey;
INT iHeight;
ULONG ulDuration;
ULONG ulMinDuration;
ULONG ulMaxDuration;
} DCWndData;
#define RETURN_VALUE 0
#define NORMAL_PROCESSING 1
#define MOVE_LEFT 2
#define MOVE_RIGHT 3
#define VERTICAL_OFFSET 2
#define HORIZONTAL_OFFSET 2
#define IDC_EDITDAYS 1000
#define IDC_EDITHOURS 1001
#define IDC_EDITMINS 1002
#define IDC_TEXTDAYS 1010
#define IDC_TEXTHOURS 1011
#define IDC_TEXTMINS 1012
#define Duration_GetPtr(hwnd) (DCWndData*)GetWindowLong((hwnd), 0)
#define Duration_SetPtr(hwnd, pDC) \
(DCWndData*)SetWindowLong((hwnd), 0, (LONG)(pDC))
// ____________________________________
//
// Private memory allocation routine
static VOID*
sAlloc (LONG size)
{
VOID* p;
p = malloc (size);
if (p)
memset (p, 0, size);
return p;
}
// ____________________________________
//
// Private memory deallocation routine
static VOID
sFree (VOID* p)
{
if (p)
free (p);
}
// ____________________________________
//
// size and position the children
static VOID
sSetControls (
HWND hwnd,
DCWndData* pDC)
{
HDC hdc = GetDC (hwnd);
INT iXpos, iXposLast;
INT i, iWidth;
HDWP hdwp;
CHAR sz[8];
HFONT hfontOrig;
SIZE size;
RECT rc;
hfontOrig = SelectObject (hdc, pDC->hFont);
hdwp = BeginDeferWindowPos (7);
// days
iXpos = HORIZONTAL_OFFSET;
i = wsprintf (sz, "%ld", pDC->iRangeHi[DAYS]);
GetTextExtentPoint32 (hdc, sz, i, &size);
iWidth = size.cx;
DeferWindowPos (hdwp, pDC->hwndEdit[DAYS], NULL,
iXpos, VERTICAL_OFFSET, iWidth, pDC->iHeight,
SWP_NOZORDER);
iXpos += iWidth;
i = lstrlen (&pDC->szText[DAYS][0]);
GetTextExtentPoint32 (hdc, &pDC->szText[DAYS][0], i, &size);
iWidth = size.cx;
DeferWindowPos (hdwp, pDC->hwndText[DAYS], NULL,
iXpos, VERTICAL_OFFSET, iWidth, pDC->iHeight,
SWP_NOZORDER);
SetWindowText (pDC->hwndText[DAYS], &pDC->szText[DAYS][0]);
// hours
iXpos += iWidth;
i = wsprintf (sz, "%ld", pDC->iRangeHi[HOURS]);
GetTextExtentPoint32 (hdc, sz, i, &size);
iWidth = size.cx;
DeferWindowPos (hdwp, pDC->hwndEdit[HOURS], NULL,
iXpos, VERTICAL_OFFSET, iWidth, pDC->iHeight,
SWP_NOZORDER);
iXpos += iWidth;
i = lstrlen (&pDC->szText[HOURS][0]);
GetTextExtentPoint32 (hdc, &pDC->szText[HOURS][0], i, &size);
iWidth = size.cx;
DeferWindowPos (hdwp, pDC->hwndText[HOURS], NULL,
iXpos, VERTICAL_OFFSET, iWidth, pDC->iHeight,
SWP_NOZORDER);
SetWindowText (pDC->hwndText[HOURS], &pDC->szText[HOURS][0]);
// minutes
iXpos += iWidth;
i = wsprintf (sz, "%ld", pDC->iRangeHi[MINS]);
GetTextExtentPoint32 (hdc, sz, i, &size);
iWidth = size.cx;
DeferWindowPos (hdwp, pDC->hwndEdit[MINS], NULL,
iXpos, VERTICAL_OFFSET, iWidth, pDC->iHeight,
SWP_NOZORDER);
iXpos += iWidth;
i = lstrlen (&pDC->szText[MINS][0]);
GetTextExtentPoint32 (hdc, &pDC->szText[MINS][0], i, &size);
iWidth = size.cx;
DeferWindowPos (hdwp, pDC->hwndText[MINS], NULL,
iXpos, VERTICAL_OFFSET, iWidth, pDC->iHeight,
SWP_NOZORDER);
SetWindowText (pDC->hwndText[MINS], &pDC->szText[MINS][0]);
iXposLast = iXpos + iWidth + HORIZONTAL_OFFSET;
GetClientRect (hwnd, &rc);
iWidth = GetSystemMetrics (SM_CXVSCROLL);
iXpos = rc.right - iWidth;
if (iXposLast > iXpos)
{
iXpos = iXposLast;
iWidth = rc.right - iXpos;
}
DeferWindowPos (hdwp, pDC->hwndUpDown, NULL,
iXpos, 0, iWidth, rc.bottom,
SWP_NOZORDER);
EndDeferWindowPos (hdwp);
SelectObject (hdc, hfontOrig);
ReleaseDC (hwnd, hdc);
}
// ____________________________________
//
// compute duration from individual values
static VOID
sComputeDuration (
DCWndData* pDC)
{
pDC->ulDuration = pDC->uValue[DAYS] * 86400;
pDC->ulDuration += pDC->uValue[HOURS] * 3600;
pDC->ulDuration += pDC->uValue[MINS] * 60;
}
// ____________________________________
//
// validate and display current duration value
static VOID
sDisplayDuration (
DCWndData* pDC)
{
CHAR sz[4];
ULONG ul;
ULONG ulSec;
if (pDC->ulDuration < pDC->ulMinDuration)
pDC->ulDuration = pDC->ulMinDuration;
if (pDC->ulDuration > pDC->ulMaxDuration)
pDC->ulDuration = pDC->ulMaxDuration;
ulSec = pDC->ulDuration;
ul = ulSec / 86400;
pDC->uValue[DAYS] = ul;
wsprintf (sz, "%ld", ul);
SetWindowText (pDC->hwndEdit[DAYS], sz);
ulSec -= ul * 86400;
ul = ulSec / 3600;
pDC->uValue[HOURS] = ul;
wsprintf (sz, "%2.2ld", ul);
SetWindowText (pDC->hwndEdit[HOURS], sz);
ulSec -= ul * 3600;
ul = ulSec / 60;
pDC->uValue[MINS] = ul;
wsprintf (sz, "%2.2ld", ul);
SetWindowText (pDC->hwndEdit[MINS], sz);
}
// ____________________________________
//
// change the duration by delta
static VOID
sScrollUnit (
DCWndData* pDC,
INT iDelta)
{
INT index;
INT i;
if (pDC->iFocused < 0)
{
index = pDC->iPrevFocused;
SetFocus (pDC->hwndEdit[index]);
}
else
index = pDC->iFocused;
i = (INT)(pDC->uValue[index]) + iDelta;
if (i < pDC->iRangeLo[index])
i = pDC->iRangeHi[index];
if (i > pDC->iRangeHi[index])
i = pDC->iRangeLo[index];
pDC->uValue[index] = i;
sComputeDuration (pDC);
sDisplayDuration (pDC);
SendMessage (pDC->hwndEdit[index], EM_SETSEL, 0, (LPARAM)-1);
}
// ____________________________________
//
// set the unit value to that specified
static VOID
sSetUnit (
DCWndData* pDC,
INT i)
{
INT index = pDC->iFocused;
if (i < pDC->iRangeLo[index])
i = pDC->iRangeHi[index];
if (i > pDC->iRangeHi[index])
i = pDC->iRangeLo[index];
pDC->uValue[index] = i;
sComputeDuration (pDC);
sDisplayDuration (pDC);
SendMessage (pDC->hwndEdit[index], EM_SETSEL, 0, (LPARAM)-1);
}
// ____________________________________
//
// common "edit" edit box subclass procedures
static UINT
sCommonEditProc (
HWND hwnd,
DCWndData* pDC,
INT index,
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
LRESULT* plReturn)
{
INT i;
UINT uRetVal;
*plReturn = 0;
uRetVal = NORMAL_PROCESSING;
switch (uMsg) {
case WM_GETDLGCODE :
*plReturn = DLGC_WANTARROWS|DLGC_WANTCHARS;
return RETURN_VALUE;
case WM_CONTEXTMENU :
case WM_MOUSEMOVE :
case WM_LBUTTONDBLCLK :
case WM_SETCURSOR :
return RETURN_VALUE;
case WM_LBUTTONDOWN :
if (pDC->iFocused == index)
return RETURN_VALUE;
break;
case WM_KILLFOCUS :
pDC->iPrevFocused = index;
pDC->iFocused = -1;
break;
case WM_SETFOCUS :
PostMessage (hwnd, EM_SETSEL, 0, (LPARAM)-1);
pDC->iFocused = index;
pDC->bFirstKey = TRUE;
break;
case WM_KEYDOWN :
switch (wParam) {
case VK_HOME :
sSetUnit (pDC, pDC->iRangeLo[index]);
uRetVal = RETURN_VALUE;
break;
case VK_END :
sSetUnit (pDC, pDC->iRangeHi[index]);
uRetVal = RETURN_VALUE;
break;
case VK_RIGHT :
uRetVal = MOVE_RIGHT;
break;
case VK_LEFT :
uRetVal = MOVE_LEFT;
break;
case VK_DOWN :
sScrollUnit (pDC, -1);
uRetVal = RETURN_VALUE;
break;
case VK_UP :
sScrollUnit (pDC, 1);
uRetVal = RETURN_VALUE;
break;
case VK_BACK :
case VK_DELETE :
uRetVal = RETURN_VALUE;
break;
}
break;
case WM_CHAR :
switch (wParam) {
case VK_BACK :
uRetVal = RETURN_VALUE;
break;
case '0' :
case '1' :
case '2' :
case '3' :
case '4' :
case '5' :
case '6' :
case '7' :
case '8' :
case '9' :
i = wParam - '0';
if (pDC->bFirstKey)
{
pDC->uValue[index] = i;
pDC->bFirstKey = FALSE;
}
else
{
i += pDC->uValue[index] * 10;
if ((i >= pDC->iRangeLo[index]) &&
(i <= pDC->iRangeHi[index]))
pDC->uValue[index] = i;
pDC->bFirstKey = TRUE;
}
sComputeDuration (pDC);
sDisplayDuration (pDC);
SendMessage (pDC->hwndEdit[index], EM_SETSEL, 0, (LPARAM)-1);
uRetVal = RETURN_VALUE;
break;
}
break;
}
return uRetVal;
}
// ______________________________________________
//
// "edit" edit box subclass procedures
static LRESULT APIENTRY
sEditDaysProc (
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
DCWndData* pDC = Duration_GetPtr(GetParent (hwnd));
LRESULT lReturn;
UINT u;
u = sCommonEditProc (hwnd, pDC, DAYS, uMsg, wParam, lParam, &lReturn);
switch (u) {
case RETURN_VALUE :
return lReturn;
case NORMAL_PROCESSING :
return CallWindowProc (pDC->wpOrigEditProc[DAYS],
hwnd, uMsg, wParam, lParam);
case MOVE_RIGHT :
SetFocus (pDC->hwndEdit[HOURS]);
return 0;
case MOVE_LEFT :
SetFocus (pDC->hwndEdit[MINS]);
return 0;
default :
return 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -