📄 wpadproc.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Module Name:
wpadproc.c
--*/
#include "multibox.h"
#include "resource.h"
#include "recog.h"
#include "windows.h"
extern HWND g_hwndHelp;
extern HWND g_hwndMain;
#ifndef UNDER_CE
#define INT16 short
#define ASSERT(x)
#endif
#ifdef DEBUG
DBGPARAM dpCurSettings;
#endif
// ====================================================================
// Globals
// ====================================================================
extern HDC g_hdcCtrl;
extern BOOL gbTimeout;
extern int gnTimeout;
extern int giMode;
extern int giSuji;
HWXGLOBAL glob;
HDC hdcMouse; // Handle to the screen DC we keep while drawing
// the mouse moves. GetDC/ReleaseDC with the region
// setup for the box is a fairly expensive operation
// and by keeping the DC setup and out we can track
// the user's writing better which is a very
// percievable feedback to the USER.
static BOOL v_bTimerStarted; // This will be initialized to FALSE
// Pens for drawing input pad.
static HPEN hpnDash;
static HPEN hpnSolid;
static HPEN hpnInk;
static WCHAR awc[256];
// The convert/space button needs some info
static int viMode; // 0 == Convert, 1 == Space
static int viDown; // Which button is currently pressed
static int viWant; // Which button was first pressed
static int vbPush; // Is there a press occuring?
// Update rectangles
static RECT varcInk[2];
static RECT varc[12];
// ====================================================================
// Local Functions
// ===============================================================[====
BOOL HandleMouseAction(HWND, UINT, PPOINT);
LRESULT HandleHWXAction(HWND, UINT);
int ConvertToString(HWXRESULTPRI *, WCHAR *);
// ====================================================================
// Local defines
// ====================================================================
// Draw a line between two or more points in internal space
void ConnectTheDots(POINT *ppt, int cpt)
{
POINT apt[2];
hpnInk = (HPEN) SelectObject(hdcMouse, hpnInk);
cpt--;
apt[1] = *ppt++;
apt[1].x = (apt[1].x >> 2); // + glob.ptClient.x;
apt[1].y = (apt[1].y >> 2); // + glob.ptClient.y;
// Always draw the initial pixel
PatBlt(hdcMouse, apt[1].x - 1, apt[1].y - 1, 2, 2, BLACKNESS);
while (cpt--)
{
apt[0] = apt[1];
apt[1] = *ppt++;
apt[1].x = (apt[1].x >> 2); // + glob.ptClient.x;
apt[1].y = (apt[1].y >> 2); // + glob.ptClient.y;
Polyline(hdcMouse, apt, 2);
}
hpnInk = (HPEN) SelectObject(hdcMouse, hpnInk);
}
int ComputeBoxKey(POINT *ppt)
{
int irc;
// See if the point is in either inking area
if (PtInRect(&varcInk[0], *ppt))
return 0;
if (PtInRect(&varcInk[1], *ppt))
return 1;
// See if it is over a button
for (irc = 0; irc < 9; irc++)
{
if (PtInRect(&varc[irc], *ppt))
return IDC_BACKSP + irc;
}
// If nothing was picked, return -1
return -1;
}
// ====================================================================
//
// WPadWndProc
//
// Window proc for writing pad window
//
// ====================================================================
LRESULT CALLBACK WPadWndProc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP)
{
HDC hdc;
switch (iMsg)
{
case WM_CREATE:
{
InitGlobals();
return 0;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, &ps);
DrawBackground(hdc);
EndPaint(hwnd, &ps);
return 0;
}
case WM_DESTROY:
// Free up the memory
if (glob.pptOut)
LocalFree(glob.pptOut);
// Delete pens used to draw input pad.
DeleteObject(hpnDash);
DeleteObject(hpnSolid);
DeleteObject(hpnInk);
return 0;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
{
POINT pt;
int ctrl;
pt.x = (INT16) LOWORD(lP);
pt.y = (INT16) HIWORD(lP);
if (g_hwndHelp)
{
if (iMsg == WM_MOUSEMOVE)
return 0;
// RAID #16146 //
if (iMsg == WM_LBUTTONUP)
break;
// RAID #16146 //
ctrl = ComputeBoxKey(&pt);
switch (ctrl)
{
case -1:
break;
case 0:
case 1:
PostMessage(g_hwndHelp, HELP_WM_COMMAND, IDC_PAD, 0);
break;
default:
PostMessage(g_hwndHelp, HELP_WM_COMMAND, ctrl, 0);
break;
}
}
else
{
if( HandleMouseAction(hwnd, iMsg, &pt) )
return 0;
}
break;
}
case WM_TIMER:
if (v_bTimerStarted)
{
KillTimer(hwnd, TIMER_ID_WPAD);
v_bTimerStarted = FALSE;
}
HandleHWXAction(hwnd, PAD_WM_DETERMINE);
return 0;
case WM_COMMAND:
{
break;
}
// User defined window messages
case PAD_WM_ERASE:
case PAD_WM_DETERMINE:
// Don't need timer any more.
if (v_bTimerStarted)
{
KillTimer(hwnd, TIMER_ID_WPAD);
v_bTimerStarted = FALSE;
}
// Now process the action.
return HandleHWXAction(hwnd, iMsg);
default:
return DefWindowProc(hwnd, iMsg, wP, lP);
}
return DefWindowProc(hwnd, iMsg, wP, lP);
}
// =====================================================================
//
// DrawBackground
//
// Erase all the inks on the writing pad.
//
// =====================================================================
void DrawBackground(HDC hdc)
{
STROKE *pst;
int i, x;
HBRUSH hbr;
POINT apt[3];
// Erase the whole thing first
hbr = (HBRUSH) SelectObject(hdc, GetStockObject(LTGRAY_BRUSH));
PatBlt(hdc, 0, 0, BOX_SIZE * 2, PadWindHeight, PATCOPY);
// Draw all the boxes.
SelectObject(hdc, GetStockObject(WHITE_BRUSH));
hpnSolid = (HPEN) SelectObject(hdc, hpnSolid);
x = 0;
for (i = 0; i < BOX_COUNT; i++)
{
Rectangle(hdc, x + BOX_OFFSET - 1, BOX_OFFSET - 1,
x + BOX_WRITING_AREA + 2,
BOX_WRITING_AREA + 2);
// If the user has never penned down in the boxes, draw the crosshairs
if (!glob.bInked)
{
apt[0].x = x + BOX_OFFSET + 2;
apt[0].y = BOX_OFFSET + 7;
apt[1].x = x + BOX_OFFSET + 2;
apt[1].y = BOX_OFFSET + 2;
apt[2].x = x + BOX_OFFSET + 7;
apt[2].y = BOX_OFFSET + 2;
Polyline(hdc, apt, 3);
apt[0].x = x + BOX_SIZE - (BOX_OFFSET + 8);
apt[0].y = BOX_OFFSET + 2;
apt[1].x = x + BOX_SIZE - (BOX_OFFSET + 3);
apt[1].y = BOX_OFFSET + 2;
apt[2].x = x + BOX_SIZE - (BOX_OFFSET + 3);
apt[2].y = BOX_OFFSET + 7;
Polyline(hdc, apt, 3);
apt[0].x = x + BOX_SIZE - (BOX_OFFSET + 3);
apt[0].y = BOX_SIZE - (BOX_OFFSET + 8);
apt[1].x = x + BOX_SIZE - (BOX_OFFSET + 3);
apt[1].y = BOX_SIZE - (BOX_OFFSET + 3);
apt[2].x = x + BOX_SIZE - (BOX_OFFSET + 8);
apt[2].y = BOX_SIZE - (BOX_OFFSET + 3);
Polyline(hdc, apt, 3);
apt[0].x = x + BOX_OFFSET + 7;
apt[0].y = BOX_SIZE - (BOX_OFFSET + 3);
apt[1].x = x + BOX_OFFSET + 2;
apt[1].y = BOX_SIZE - (BOX_OFFSET + 3);
apt[2].x = x + BOX_OFFSET + 2;
apt[2].y = BOX_SIZE - (BOX_OFFSET + 8);
Polyline(hdc, apt, 3);
apt[0].x = x + BOX_SIZE / 2 - 4;
apt[0].y = BOX_SIZE / 2;
apt[1].x = x + BOX_SIZE / 2 + 5;
apt[1].y = BOX_SIZE / 2;
Polyline(hdc, apt, 2);
apt[0].x = x + BOX_SIZE / 2;
apt[0].y = BOX_SIZE / 2 - 4;
apt[1].x = x + BOX_SIZE / 2;
apt[1].y = BOX_SIZE / 2 + 5;
Polyline(hdc, apt, 2);
}
x += BOX_SIZE;
}
hpnSolid = (HPEN) SelectObject(hdc, hpnSolid);
// Set it so we know we don't have to erase any ink.
glob.iPrevBox = -1;
// Redraw the current character.
pst = glob.pstrk;
while (pst)
{
ConnectTheDots(pst->apt, pst->cpt);
pst = pst->pNext;
}
SelectObject(hdc, hbr);
// Now, draw all the buttons. The first row are variable width
BitBlt(hdc, BUTTON_COL_00, BUTTON_ROW_00, BCKSP_BUTTON_WIDTH, SMALL_BUTTON_HEIGHT,
g_hdcCtrl, viDown == IDC_BACKSP ? LARGE_BUTTON_WIDTH : 0, BMP_ROW_BACKSP, SRCCOPY);
BitBlt(hdc, BUTTON_COL_01, BUTTON_ROW_00, ESCAP_BUTTON_WIDTH, SMALL_BUTTON_HEIGHT,
g_hdcCtrl, viDown == IDC_ESCAPE ? LARGE_BUTTON_WIDTH : 0, BMP_ROW_ESCAPE, SRCCOPY);
BitBlt(hdc, BUTTON_COL_02, BUTTON_ROW_00, QUERY_BUTTON_WIDTH, SMALL_BUTTON_HEIGHT,
g_hdcCtrl, viDown == IDC_QUERY ? LARGE_BUTTON_WIDTH : 0, BMP_ROW_HELP, SRCCOPY);
// The second row are 'sticky' buttons.
BitBlt(hdc, BUTTON_COL_00, BUTTON_ROW_01, LARGE_BUTTON_WIDTH, LARGE_BUTTON_HEIGHT,
g_hdcCtrl, (giMode || (viDown == IDC_WIDTH)) ? LARGE_BUTTON_WIDTH : 0, BMP_ROW_ZENKAKU, SRCCOPY);
BitBlt(hdc, BUTTON_COL_03, BUTTON_ROW_01, LARGE_BUTTON_WIDTH, LARGE_BUTTON_HEIGHT,
g_hdcCtrl, (giSuji || (viDown == IDC_SUJI)) ? LARGE_BUTTON_WIDTH : 0, BMP_ROW_SUJI, SRCCOPY);
// The rest are normal
BitBlt(hdc, BUTTON_COL_00, BUTTON_ROW_02, LARGE_BUTTON_WIDTH, LARGE_BUTTON_HEIGHT,
g_hdcCtrl, viDown == IDC_RECOG ? LARGE_BUTTON_WIDTH : 0, BMP_ROW_RECOG, SRCCOPY);
BitBlt(hdc, BUTTON_COL_03, BUTTON_ROW_02, LARGE_BUTTON_WIDTH, LARGE_BUTTON_HEIGHT,
g_hdcCtrl, viDown == IDC_ENTER ? LARGE_BUTTON_WIDTH : 0, BMP_ROW_ENTER, SRCCOPY);
BitBlt(hdc, BUTTON_COL_00, BUTTON_ROW_03, LARGE_BUTTON_WIDTH, LARGE_BUTTON_HEIGHT,
g_hdcCtrl, viDown == IDC_SPACE ? LARGE_BUTTON_WIDTH : 0, BMP_ROW_SPACE, SRCCOPY);
BitBlt(hdc, BUTTON_COL_03, BUTTON_ROW_03, LARGE_BUTTON_WIDTH, LARGE_BUTTON_HEIGHT,
g_hdcCtrl, viDown == IDC_CONVERT ? LARGE_BUTTON_WIDTH : 0, BMP_ROW_CONVERT, SRCCOPY);
}
// =====================================================================
//
// InitGlobals
//
// Initialize the writing pad specific globals.
//
// =====================================================================
void InitGlobals(void)
{
LOGPEN logpen;
// WCHAR awc[40];
hdcMouse = NULL;
glob.pstrk = (STROKE *) NULL;
glob.cptRaw = 0;
glob.pptOut = (POINT *) LocalAlloc(LPTR, 16 * sizeof(POINT));
glob.cptOut = 0;
glob.maxOut = 16;
glob.iLogBox = 0;
glob.bNumeric = FALSE;
glob.iPrevBox = -1;
glob.iCurrBox = -1;
logpen.lopnStyle = PS_DASH;
logpen.lopnWidth.x = 0;
logpen.lopnWidth.y = 0;
logpen.lopnColor = RGB(128, 128, 128);
hpnDash = CreatePenIndirect(&logpen);
logpen.lopnStyle = PS_SOLID;
logpen.lopnWidth.x = 0;
logpen.lopnWidth.y = 0;
logpen.lopnColor = RGB(128, 128, 128);
hpnSolid = CreatePenIndirect(&logpen);
// wsprintf(awc, TEXT("hpnSolid = %08x\n"), hpnSolid);
// OutputDebugString(awc);
logpen.lopnStyle = PS_SOLID;
logpen.lopnWidth.x = 2;
logpen.lopnWidth.y = 2;
logpen.lopnColor = RGB(0, 0, 0);
hpnInk = CreatePenIndirect(&logpen);
// We need to eventually delete these objects
// DeleteObject(hpn);
// Compute the update rectangles
varcInk[0].top = BOX_OFFSET;
varcInk[0].left = BOX_OFFSET;
varcInk[0].bottom = varcInk[0].top + BOX_WRITING_AREA;
varcInk[0].right = varcInk[0].left + BOX_WRITING_AREA;
varcInk[1].left = BOX_SIZE + BOX_OFFSET;
varcInk[1].top = BOX_OFFSET;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -