📄 crosswordsample.cpp
字号:
void OnCommandToolsOptions(HWND hWnd)
{
PROPSHEETPAGE psp[2];
psp[0].dwSize = sizeof(psp[0]);
psp[0].dwFlags = PSP_DEFAULT;
psp[0].hInstance = g_hInst;
psp[0].pszTemplate = MAKEINTRESOURCE(IDD_TOOLS_OPTIONS_1);
psp[0].pfnDlgProc = (DLGPROC)&ToolsOptionsDialog1;
psp[1].dwSize = sizeof(psp[1]);
psp[1].dwFlags = PSP_DEFAULT;
psp[1].hInstance = g_hInst;
psp[1].pszTemplate = MAKEINTRESOURCE(IDD_TOOLS_OPTIONS_2);
psp[1].pfnDlgProc = (DLGPROC)&ToolsOptionsDialog2;
//
// See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/win_ce/htm/pwc_propertysheets.asp
// for more information about PSH_MAXIMIZE and handling PSCB_GETVERSION in the
// PropertySheet callback.
//
PROPSHEETHEADER psh;
psh.dwSize = sizeof(psh);
psh.dwFlags = PSH_DEFAULT | PSH_PROPSHEETPAGE | PSH_MAXIMIZE | PSH_NOAPPLYNOW | PSH_USECALLBACK;
psh.hwndParent = hWnd;
psh.hInstance = g_hInst;
psh.pszCaption = _T("Tools / Options");
psh.nPages = 2;
psh.nStartPage = 0;
psh.ppsp = &psp[0];
psh.pfnCallback = PropSheetCallback;
PropertySheet(&psh);
}
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: OnClickEnterButton
//
// PURPOSE: Called when the enter button is clicked. Copies the text in the
// g_hwndEditBox to the crossword offscreen buffer (using DrawHint).
//
// ON ENTRY:
// HWND hWnd: the main window app.
// g_selectedHint: the destination row or column the text will
// be copied to.
//
// ON EXIT:
// The edit box is cleared.
//
void OnClickEnterButton(HWND hWnd)
{
WCHAR szBuffer[80];
SendDlgItemMessage(hWnd, IDC_MAIN_EDIT_BOX, WM_GETTEXT, sizeof(szBuffer)/sizeof(WCHAR), (LPARAM)szBuffer);
SendDlgItemMessage(hWnd, IDC_MAIN_EDIT_BOX, WM_SETTEXT, 0, (LPARAM)_T(""));
if (g_selectedHint == -1) return;
for (int i = 0; i < g_hints[g_selectedHint].cLetters; i++)
{
if (szBuffer[i] == '\0')
{
break;
}
int x = g_hints[g_selectedHint].x + (g_hints[g_selectedHint].fDown ? 0 : i);
int y = g_hints[g_selectedHint].y + (g_hints[g_selectedHint].fDown ? i : 0);
g_crossword[y][x] = towupper(szBuffer[i]);
}
DrawHint(hWnd, g_selectedHint, RGB(128,0,0));
}
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: OnLButtonDown
//
// PURPOSE: Called when the stylus is tapped on the screen. Selects a row or
// column based on the location of the tap.
//
// ON ENTRY:
// HWND hWnd: the window which was tapped.
// INT x: the x location of the screen tap in pixels.
// INT y: the y location of the screen tap in pixels.
//
// ON EXIT:
// g_selectedHint equals the location of the screen tap.
//
void OnLButtonDown(HWND hWnd, INT x, INT y)
{
x = (x - SCALEX(8)) / SCALEX(16);
y = (y - SCALEY(26)) / SCALEY(16);
if (x < 0 || y < 0 || x >= CROSSWORD_X - 1 || y >= CROSSWORD_Y - 1)
{
return;
}
//
// Erase the old hint.
//
DrawHint(hWnd, g_selectedHint, RGB(255,255,255));
//
// Search for the hint that we clicked.
//
int oldSelectedHint = g_selectedHint;
g_selectedHint = -1;
for (int i = 0; i < sizeof(g_hints) / sizeof(CROSSWORD_HINT); i++)
{
if (i == oldSelectedHint) continue;
if ((!g_hints[i].fDown && y == g_hints[i].y &&
x >= g_hints[i].x && x < g_hints[i].x + g_hints[i].cLetters) ||
(g_hints[i].fDown && x == g_hints[i].x &&
y >= g_hints[i].y && y < g_hints[i].y + g_hints[i].cLetters))
{
g_selectedHint = i;
break;
}
}
//
// Draw in this new hint.
//
DrawHint(hWnd, g_selectedHint, RGB(128, 0, 0));
if (g_selectedHint != -1)
{
SendDlgItemMessage(hWnd, IDC_MAIN_EDIT_BOX, EM_LIMITTEXT, g_hints[g_selectedHint].cLetters, 0);
}
//
// Invalidate the hint area so we redraw.
//
RECT rTallMode = { SCALEX(0), SCALEY(189), SCALEX(240), SCALEY(320) };
RECT rWideMode = { SCALEX(240), SCALEY(26), SCALEX(320), SCALEY(240) };
InvalidateRect(hWnd, InWideMode() ? &rWideMode : &rTallMode, FALSE);
}
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: OnPaint
//
// PURPOSE: Paints the main application window.
//
// ON ENTRY:
// HWND hWnd: the window to paint.
//
void OnPaint(HWND hWnd)
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
//
// Draw background (we made the bitmap 320x320 so to work in landscape mode also).
//
int nImageSize = DRA::LogPixelsX() >= 192 ? 640 : 320;
HBITMAP hBMP = LoadBitmap(g_hInst, DRA::LogPixelsX() >= 192 ?
MAKEINTRESOURCE(IDB_BACKGROUND_1_HIDPI) :
MAKEINTRESOURCE(IDB_BACKGROUND_1));
HDC hMemDC = CreateCompatibleDC(hDC);
HBITMAP hOldBMP = (HBITMAP)SelectObject(hMemDC, hBMP);
StretchBlt(hDC, 0, 0, SCALEX(320), SCALEY(320), hMemDC, 0, 0, nImageSize, nImageSize, SRCCOPY);
SelectObject(hMemDC, hOldBMP);
DeleteObject(hBMP);
DeleteDC(hMemDC);
//
// Draw crossword.
//
TransparentImage(hDC,
SCALEX(8),
SCALEY(26),
14 * SCALEX(16) + 1,
10 * SCALEY(16) + 1,
g_hMemDC,
0,
0,
14 * SCALEX(16) + 1,
10 * SCALEX(16) + 1,
RGB(255, 255, 255));
HPEN hNewPen = CreatePen(PS_SOLID, SCALEX(1), RGB(0, 0, 0));
HPEN hOldPen = (HPEN)SelectObject(hDC, hNewPen);
POINT line[] = { {SCALEX(0), SCALEY(188)}, {SCALEX(240), SCALEY(188)} };
Polyline(hDC, line, 2);
//
// Erase the hint area using a pattern brush.
//
RECT rTallMode = { SCALEX(25), SCALEY(200), SCALEX(230), SCALEY(245) };
RECT rWideMode = { SCALEX(240), SCALEY(43), SCALEX(311), SCALEY(185) };
RECT& r = InWideMode() ? rWideMode : rTallMode;
HBITMAP hPattern = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_PATTERN));
HBRUSH hNewBrush = CreatePatternBrush(hPattern);
HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, hNewBrush);
Rectangle(hDC, r.left, r.top, r.right, r.bottom);
SelectObject(hDC, hOldBrush);
DeleteObject(hNewBrush);
DeleteObject(hPattern);
SelectObject(hDC, hOldPen);
DeleteObject(hNewPen);
if (g_selectedHint != -1)
{
//
// Print the hint out at bottom.
//
r.left += SCALEX(4);
r.right -= SCALEX(4);
SetBkMode(hDC, TRANSPARENT);
HFONT hOldFont = (HFONT)SelectObject(hDC, g_hFont);
DrawText(hDC, g_hints[g_selectedHint].szHint, -1, &r, DT_TOP | DT_LEFT | DT_WORDBREAK);
SelectObject(hDC, hOldFont);
//
// Display an arrow next to the hint.
//
POINT rgArrow[] = { {0,3}, {6,3}, {6,0}, {12, 5}, {6, 10}, {6, 7}, {0, 7} };
for (int i = 0; i < 7; i++)
{
//
// A vertical arrow is a horizontal arrow with X and Y flipped.
//
if (g_hints[g_selectedHint].fDown)
{
int t = rgArrow[i].x;
rgArrow[i].x = rgArrow[i].y;
rgArrow[i].y = t;
}
rgArrow[i].x += (InWideMode() ? 280 : 5);
rgArrow[i].y += (InWideMode() ? 26 : 200);
DRA::SCALEPT(rgArrow[i]);
}
Polygon(hDC, rgArrow, 7);
}
EndPaint(hWnd, &ps);
}
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: WndProc()
//
// PURPOSE: Processes messages for the main window.
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_SH_UIMETRIC_CHANGE)
{
CreateHintFont();
}
else switch (message)
{
case WM_CREATE:
g_hwndCB = CreateRpCommandBar(hWnd);
memset (&g_sai, 0, sizeof (g_sai));
g_sai.cbSize = sizeof (g_sai);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_MAIN_ENTER_BUTTON:
OnClickEnterButton(hWnd);
break;
case ID_TOOLS_OPTIONS:
OnCommandToolsOptions(hWnd);
break;
case ID_TOOLS_ABOUT:
DialogBox(g_hInst, MAKEINTRESOURCE(IDD_TOOLS_ABOUT), hWnd, &ToolsAboutDialog);
break;
}
break;
case WM_DRAWITEM:
{
//
// Draws the Enter button.
//
LPDRAWITEMSTRUCT lpDis = (LPDRAWITEMSTRUCT)lParam;
DrawEdge(lpDis->hDC, &lpDis->rcItem,
(lpDis->itemState & ODS_SELECTED) ? EDGE_SUNKEN : EDGE_RAISED,
BF_RECT | BF_ADJUST);
ImageList_Draw(g_hImageList,
(lpDis->itemState & ODS_SELECTED) ? 0 : 1,
lpDis->hDC, lpDis->rcItem.left, lpDis->rcItem.top, ILD_NORMAL);
}
break;
case WM_PAINT:
OnPaint(hWnd);
break;
case WM_LBUTTONDOWN:
OnLButtonDown(hWnd, LOWORD(lParam), HIWORD(lParam));
break;
case WM_DESTROY:
CommandBar_Destroy(g_hwndCB);
PostQuitMessage(0);
break;
case WM_ACTIVATE:
SHHandleWMActivate(hWnd, wParam, lParam, &g_sai, FALSE);
break;
case WM_SETTINGCHANGE:
SHHandleWMSettingChange(hWnd, wParam, lParam, &g_sai);
break;
case WM_SIZE:
{
HWND hEditBox = GetDlgItem(hWnd, IDC_MAIN_EDIT_BOX);
HWND hEnterButton = GetDlgItem(hWnd, IDC_MAIN_ENTER_BUTTON);
INT nWidth = LOWORD(lParam);
MoveWindow(hEditBox, SCALEX(8), SCALEY(4), nWidth - SCALEX(70), SCALEY(20), TRUE);
MoveWindow(hEnterButton, nWidth - SCALEX(57), SCALEY(4), SCALEX(50), SCALEY(20), TRUE);
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: InWideMode()
//
// PURPOSE: returns true if there is not enough space to display the
// crossword in "tall mode".
//
BOOL InWideMode()
{
int height = GetSystemMetrics(SM_CYSCREEN);
return (height < SCALEY(320)) ? TRUE : FALSE;
}
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: CreateHintFont()
//
// PURPOSE: Queries SHGetUIMetrics to get the current font, then creates
// g_hFont.
//
void CreateHintFont()
{
if (g_hFont)
{
DeleteObject(g_hFont);
}
DWORD dwRequired;
LONG dwFontSize = 12;
SHGetUIMetrics(SHUIM_FONTSIZE_PIXEL, &dwFontSize, sizeof(dwFontSize), &dwRequired);
LOGFONT lf;
memset(&lf, 0, sizeof(lf));
_tcscpy(lf.lfFaceName, _T("Courier New"));
lf.lfHeight = -dwFontSize;
lf.lfWeight = FW_NORMAL;
g_hFont = CreateFontIndirect(&lf);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -