📄 crosswordsample.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// CrosswordSample.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "CrosswordSample.h"
const int MAX_LOADSTRING = 100;
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: WinMain
//
// PURPOSE: Entry point of our application.
//
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HACCEL hAccelTable;
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_CROSSWORDSAMPLE);
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: MyRegisterClass
//
// PURPOSE: Registers the window class for the main window.
//
// ON ENTRY:
// HINSTANCE hInstance: the application instance.
// LPTSTR szWindowClass: the window class name to register.
//
// ON EXIT:
// The window class is registered and the return value
// from RegisterClass is returned.
//
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CROSSWORDSAMPLE));
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = szWindowClass;
return RegisterClass(&wc);
}
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: CreateRpCommandBar
//
// PURPOSE: Creates the command bar at the bottom of the window.
//
// ON ENTRY:
// HWND hwnd: the window which will recieve the command bar.
// g_hInst: the application instance.
//
// ON EXIT:
// The HWND of the command bar.
//
HWND CreateRpCommandBar(HWND hwnd)
{
SHMENUBARINFO mbi;
memset(&mbi, 0, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = hwnd;
mbi.nToolBarId = IDM_MENU;
mbi.hInstRes = g_hInst;
mbi.nBmpId = 0;
mbi.cBmpImages = 0;
if (!SHCreateMenuBar(&mbi))
return NULL;
CommandBar_AddBitmap (mbi.hwndMB, g_hInst, IDR_TOOLBAR1, 4, 16, 15);
return mbi.hwndMB;
}
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: InitInstance
//
// PURPOSE: Saves instance handle to g_hInst and creates the main window.
//
// ON ENTRY:
// HINSTANCE hInstance: the application instance.
// int nCmdShow: the hide/show parameter from WinMain.
//
// ON EXIT:
// g_hInst is initialized.
// Returns TRUE if all initialization completed successfully.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd = NULL;
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];
g_hInst = hInstance;
LoadString(hInstance, IDC_CROSSWORDSAMPLE, szWindowClass, MAX_LOADSTRING);
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
//
// If the app is already running, find it and bring it to the foreground.
// (the "| 0x01" is used to bring any owned windows to the foreground).
//
hWnd = FindWindow(szWindowClass, szTitle);
if (hWnd)
{
SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001));
return 0;
}
//
// Create the main window.
//
MyRegisterClass(hInstance, szWindowClass);
hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
//
// Initialize the crossword data structures.
//
CreateCrossword();
//
// Create all child windows.
//
CreateWindow(_T("Edit"), NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL,
8, 4, 170, 20,
hWnd, (HMENU)IDC_MAIN_EDIT_BOX, g_hInst, 0);
CreateWindow(_T("Button"), _T(""),
WS_VISIBLE | WS_CHILD | BS_OWNERDRAW,
183, 4, 50, 20,
hWnd, (HMENU)IDC_MAIN_ENTER_BUTTON, g_hInst, 0);
//
// This magic control automatically brings up the SIP when focus
// is transferred to an editable control.
//
SHInitExtraControls();
CreateWindow(WC_SIPPREF, NULL,
WS_CHILD,
0,0,0,0,
hWnd, NULL, g_hInst, 0);
//
// Create the default font.
//
LOGFONT lf;
memset(&lf, 0, sizeof(lf));
lf.lfHeight = -12;
_tcscpy(lf.lfFaceName, _T("Courier New"));
lf.lfWeight = FW_NORMAL;
g_hFont = CreateFontIndirect(&lf);
//
// Load the images for the ENTER button.
//
g_hImageList = ImageList_LoadImage(
g_hInst,
MAKEINTRESOURCE(IDB_ENTERBTN),
46,
0,
CLR_NONE,
IMAGE_BITMAP,
0);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: CreateCrossword
//
// PURPOSE: Creates the crossword bitmaps and does all initial drawing.
//
// ON EXIT: g_hMemDC, g_hMemBitmap, g_selectedClue, g_crossword
// are initialized.
//
void CreateCrossword()
{
HDC hScreenDC = GetWindowDC(NULL);
g_hMemDC = CreateCompatibleDC(hScreenDC);
g_hMemBitmap = CreateCompatibleBitmap(hScreenDC, 240, 320);
ReleaseDC(NULL, hScreenDC);
SelectObject(g_hMemDC, g_hMemBitmap);
int iHint = 0;
//
// Fill in each g_hints structure from left to right (for ACROSS hints).
//
for (int y = 0; y < CROSSWORD_Y - 1; y++)
{
int cLetters = 0;
for (int x = 0; x < CROSSWORD_X; x++)
{
if (g_crosswordSolution[y][x] == '*')
{
SelectObject(g_hMemDC, GetStockObject(BLACK_BRUSH));
if (cLetters > 1)
{
g_hints[iHint].x = x - cLetters;
g_hints[iHint].y = y;
g_hints[iHint].cLetters = cLetters;
g_hints[iHint].fDown = false;
iHint++;
}
cLetters = 0;
}
else
{
SelectObject(g_hMemDC, GetStockObject(WHITE_BRUSH));
cLetters++;
}
//
// Also draw the offscreen crossword bitmap during this pass.
//
RECT r;
r.left = 16 * x;
r.top = 16 * y;
r.right = r.left + 17;
r.bottom = r.top + 17;
Rectangle(g_hMemDC, r.left, r.top, r.right, r.bottom);
g_crossword[y][x] = ' ';
}
}
//
// Fill in each g_hints structure from top to bottom (for DOWN hints).
//
for (int x = 0; x < CROSSWORD_X - 1; x++)
{
int cLetters = 0;
for (int y = 0; y < CROSSWORD_Y; y++)
{
if (g_crosswordSolution[y][x] == '*')
{
if (cLetters > 1)
{
g_hints[iHint].x = x;
g_hints[iHint].y = y - cLetters;
g_hints[iHint].cLetters = cLetters;
g_hints[iHint].fDown = true;
iHint++;
}
cLetters = 0;
}
else
{
cLetters++;
}
}
}
g_selectedHint = -1;
}
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: DrawHint
//
// PURPOSE: Draws the row or column specified by the given hint onto the
// crossword offscreen buffer (g_hMemDC).
//
// ON ENTRY:
// HWND hWnd: the main window app (we need this to invalidate the window
// after we are done, so that it will send WM_PAINT).
// INT nHint: the hint whose row or column we wish to draw.
// COLORREF rgbColor: the background color of the squares we draw.
//
void DrawHint (HWND hWnd, INT nHint, COLORREF rgbColor)
{
if (nHint == -1) return;
HBRUSH hBrush = CreateSolidBrush(rgbColor);
for (int i = 0; i < g_hints[nHint].cLetters; i++)
{
RECT r;
int x = g_hints[nHint].x + (g_hints[nHint].fDown ? 0 : i);
int y = g_hints[nHint].y + (g_hints[nHint].fDown ? i : 0);
r.left = x * 16 + 1;
r.top = y * 16 + 1;
r.right = r.left + 15;
r.bottom = r.top + 15;
SetBkMode(g_hMemDC, TRANSPARENT);
FillRect(g_hMemDC, &r, hBrush);
DrawText(g_hMemDC, &g_crossword[y][x], 1, &r, DT_CENTER | DT_VCENTER);
//
// Invalidate the rectangle on the screen.
//
r.left += 8;
r.right += 8;
r.top += 26;
r.bottom += 26;
InvalidateRect(hWnd, &r, false);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -