Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.77 MB, 281 trang )
<span class='text_page_counter'>(1)</span><div class='page_container' data-page=1></div>
<span class='text_page_counter'>(2)</span><div class='page_container' data-page=2>
Hình 1-1 – Biểu tượng chuẩn trong Windows
#include <windows.h>
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
// Initialize global strings
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
// FUNCTION: MyRegisterClass()
// PURPOSE: Registers the window class.
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
PAINTSTRUCT ps;
HDC hdc;
LPSTR szHello = "Hello, world";
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_SINGLELINE
| DT_CENTER | DT_VCENTER);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
hwndPrev = FindWindow(“HelloAppClass”, 0);
if (hwndPrev)
{
// switch to prev ver
}
int cbWndExtra;
HANDLE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
HICON hIconSm;
} WNDCLASSEX;
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
RegisterClassEx(&wcex);
<i><b> HMENU hMenu, // handle to menu or child-window identifier </b></i>
<i><b> HANDLE hInstance, // handle to application instance </b></i>
<i><b> LPVOID lpParam // pointer to window-creation data </b></i>
<b>); </b>
<b>HWND CreateWindowEx( </b>
<i><b> DWORD dwExStyle, // extended window style </b></i>
<i><b> LPCTSTR lpClassName, // pointer to registered class name </b></i>
<i><b> LPCTSTR lpWindowName, // pointer to window name </b></i>
<i><b> DWORD dwStyle, // window style </b></i>
<i><b> int x, // horizontal position of window </b></i>
<i><b> int y, // vertical position of window </b></i>
<i><b> int nWidth, // window width </b></i>
<i><b> int nHeight, // window height </b></i>
<i><b> HWND hWndParent, // handle to parent or owner window </b></i>
<i><b> HMENU hMenu, // handle to menu, or child-window identifier </b></i>
<i><b> HINSTANCE hInstance, // handle to application instance </b></i>
<i><b> LPVOID lpParam // pointer to window-creation data </b></i>
<b>); </b>
Ví duï
hWnd = CreateWindow(
szWindowClass, // Window class name
“Hello program”, // Window name
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // horizontal position of window
0, // vertical position of window
CW_USEDEFAULT, // window width
0, // window height
NULL, // parent window handle
NULL, // handle to menu, or child-window identifier
hInstance, // handle to application instance
NULL); // pointer to window-creation data
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
switch (message)
{
case WM_CREATE:
// Xu ly thong diep WM_CREATE
break;
•
Hình 1-2 – Taïo project trong VC++ 6.0
Hình 2-2 – Các vùng xén tạo nên các hàng rào không cho phép ứng dụng
này vẽ lên cửa sổ ứng dụng khác
case WM_CHAR:
hdc = GetDC(hWnd);
ReleaseDC(hWnd, hdc);
break;
stdafx.h
stdafx.cpp
pixel.cpp
// Trich doan pixel.cpp
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
typedef struct _RECT { // rc
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT;
#define MAX_MARKERS 100
#define MARKER_SIZE 5
void DrawMarker(HDC hdc, POINT pt, int size);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
PAINTSTRUCT ps;
HDC hdc;
int i;
static POINT apt[MAX_MARKERS];
static int nMarkers = 0;
switch (message)
{
case WM_LBUTTONDOWN:
if (nMarkers <= MAX_MARKERS)
{
apt[nMarkers].x = LOWORD(lParam);
apt[nMarkers].y = HIWORD(lParam);
nMarkers++;
InvalidateRect(hWnd, NULL, TRUE);
}
break;
case WM_RBUTTONDOWN:
nMarkers = 0;
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
for (i = 0; i < nMarkers; i++)
DrawMarker(hdc, apt[i], MARKER_SIZE);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
for (i = 1; i <= size; i++)
{
InvertPixel(hdc, x-i, y);
InvertPixel(hdc, x+i, y);
}
typedef struct tagPAINTSTRUCT
{ // ps
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32];
} PAINTSTRUCT;
// Marker ver 1.1 : Chi ve lai phan hinh chu nhat vua du chua marker
case WM_LBUTTONDOWN:
if (nMarkers <= MAX_MARKERS)
{
apt[nMarkers].x = LOWORD(lParam);
apt[nMarkers].y = HIWORD(lParam);
nMarkers++;
r.bottom = HIWORD(lParam) + MARKER_SIZE + 1;
r.top = HIWORD(lParam) - MARKER_SIZE - 1;
r.left = LOWORD(lParam) - MARKER_SIZE - 1;
r.right = LOWORD(lParam) + MARKER_SIZE + 1;
InvalidateRect(hWnd, &r, TRUE);
}
break;
void InvertPixel(HDC hdc, int x, int y)
{
}
// Marker.cpp : Defines the entry point for the application.
// Version 1.2: Dung GetDC de ve ngay khi bam mat trai chuot
// Trich doan phan WndProc
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
#define MAX_MARKERS 100
#define MARKER_SIZE 5
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
int i;
static POINT apt[MAX_MARKERS];
static int nMarkers = 0;
switch (message)
{
case WM_LBUTTONDOWN:
if (nMarkers <= MAX_MARKERS)
{
apt[nMarkers].x = LOWORD(lParam);
apt[nMarkers].y = HIWORD(lParam);
nMarkers++;
hdc = GetDC(hWnd);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
typedef struct tagPOINT
{
LONG x;
LONG y;
} POINT;
BOOL MoveToEx(
<i>HDC hdc, </i>
<i>int X, int Y, </i>
LPPOINT lpPoint
);
BOOL LineTo(
<i><b>CONST POINT *lppt, </b></i> // pointer to array containing endpoints
<i><b>int cPoints </b></i> // number of points in the array
<b>); </b>
<b>BOOL PolylineTo( </b>
<i><b>HDC hdc, </b></i> // handle to device context
<i><b>CONST POINT *lppt, </b></i> // pointer to array of points
<i><b>DWORD cCount </b></i> // number of points in array
<b>); </b>
<b>BOOL PolyPolyline( </b>
<i><b>HDC hdc, </b></i> // handle of a device context
<i><b>CONST POINT *lppt, </b></i> // address of an array of points
<i><b>CONST DWORD *lpdwPolyPoints, </b></i> // address of an array of values
<i><b>DWORD cCount </b></i> // number of counts in the second array
<b>); </b>
#include "stdafx.h"
#include "resource.h"
#define MAX_SEGS 100
#define MAX_POINTS 10000
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szPrompt[MAX_LOADSTRING];
LoadString(hInst, IDS_PROMPT, szPrompt, MAX_LOADSTRING);
int i,j;
static int nSegs, nPoints;
static int anCounts[MAX_SEGS+1];
static BOOL bMouseDown;
static POINT oldPoint, apt[MAX_POINTS];
switch (message)
{
case WM_LBUTTONDOWN:
if (nSegs < MAX_SEGS && nPoints < MAX_POINTS)
{
bMouseDown = TRUE;
SetCapture(hWnd);
anCounts[nSegs] = nPoints;
apt[nPoints].x = LOWORD(lParam);
apt[nPoints++].y = HIWORD(lParam);
nSegs++;
}
break;
case WM_MOUSEMOVE:
if (bMouseDown)
{
if (nPoints < MAX_POINTS)
{
case WM_RBUTTONDOWN:
nSegs = nPoints = 0;
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, szPrompt, strlen(szPrompt), &rt, DT_CENTER);
for (i = 0; i < nSegs; i++)
{
j = anCounts[i];
MoveToEx(ps.hdc, apt[j].x, apt[j].y, &oldPoint);
for (; j < anCounts[i+1]; j++)
LineTo(ps.hdc, apt[j].x, apt[j].y);
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
return 0;
}
<i><b>HDC hdc, </b></i> // handle to device context
<i><b>int nLeftRect, </b></i> // x-coord : UPL
<i><b>int nTopRect, </b></i> // y-coord : UPL
<i><b>int nRightRect, </b></i> // x-coord : LWR
<b>BOOL ArcTo( </b>
<i><b>HDC hdc, </b></i> <b>// handle to device context </b>
<i><b>int nLeftRect, </b></i> <b>// x-coord : UPL </b>
<i><b>int nTopRect, </b></i> <b>// y-coord : UPL </b>
<i><b>int nRightRect, </b></i> <b>// x-coord : LWR </b>
<i><b>int nBottomRect, </b></i> <b>// y-coord : LWR </b>
<i><b>int nXRadial1, </b></i> <b>// x-coord of the first radial ending point </b>
<i><b>int nYRadial1, </b></i> <b>// y-coord of the first radial ending point </b>
<i><b>int nXRadial2, </b></i> <b>// x-coord of the second radial ending point </b>
<i><b>int nYRadial2 </b></i> // y-coord of the second radial ending point
<b>); </b>
<i><b>HDC hdc, </b></i> <b>// handle to device context </b>
<i><b> int X, </b></i> // x-coordinate of circle's center
<i><b> int Y, </b></i> // y-coordinate of circle's center
<i><b> DWORD dwRadius, </b></i> // circle's radius
<i><b> FLOAT eStartAngle, </b></i> // arc's start angle
<i><b> FLOAT eSweepAngle // arc's sweep angle </b></i>
<b> ); </b>
<i><b>HDC hdc, // handle to device context </b></i>
<i><b>CONST POINT *lppt, // pointer to endpoints and control points </b></i>
<i><b>DWORD cPoints // count of endpoints and control points </b></i>
<b> ); </b>
<i><b>COLORREF SetBkColor(HDC hdc, COLORREF crColor); </b></i>
<i><b>int SetBkMode(HDC hdc, int iBkMode); </b></i>
hpenOld = SelectObject(hdc, hPenNew);
SelectObject(hdc, hPenOld);
HPEN hpen;
hpen = CreatePen (nPenStyle, nWidth, crColor);
hpen = CreatePen (PS_SOLID, R, RGB(255,0,0));
PS_SOLID Pen is solid.
PS_DASH Pen is dashed.
PS_DOT Pen is dotted.
PS_DASHDOT Pen has alternating dashes and dots.
PS_DASHDOTDOT Pen has dashes and double dots.
PS_NULL Pen is invisible.
PS_INSIDEFRAME Pen is solid, to be drawn inside a filled figure
typedef struct tagLOGPEN { // lgpn
POINT lopnWidth;
COLORREF lopnColor;
} LOGPEN;
Hình 3-3 – Pen
// Pen.cpp : Defines the entry point for the application.
// Trich doan ham WndProc
#define dim(a) sizeof(a)/sizeof(a[0])
struct PenData
{
char *Name;
int nWidth, nStyle;
COLORREF crColor;
};
PenData aPenTab[] =
{
int i;
HPEN hpen
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
for (i = 0; i < dim(aPenTab); i++)
{
TextOut(hdc, 10, i*30, aPenTab[i].Name,
lstrlen(aPenTab[i].Name));
hpen = CreatePen(aPenTab[i].nStyle,
aPenTab[i].nWidth,
aPenTab[i].crColor);
SelectObject(hdc, hpen);
MoveToEx(hdc, 150, i*30+10, NULL);
LineTo(hdc, 500, i*30+10);
DeleteObject(hpen);
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
<b>int SetROP2( </b>
<i><b>HDC hdc, </b></i> // handle of device context
<b> </b> <i><b>int fnDrawMode </b></i> // drawing mode
<b> ); </b>
R2_MASKPEN Pixel is a combination of the colors common to both the pen and the screen.
R2_MASKPENNOT Pixel is a combination of the colors common to both the pen and the inverse of
the screen.
R2_MERGENOTPEN Pixel is a combination of the screen color and the inverse of the pen color.
R2_MERGEPEN Pixel is a combination of the pen color and the screen color.
R2_MERGEPENNOT Pixel is a combination of the pen color and the inverse of the screen color.
R2_NOP Pixel remains unchanged.
R2_NOT Pixel is the inverse of the screen color.
R2_NOTCOPYPEN Pixel is the inverse of the pen color.
R2_NOTMASKPEN Pixel is the inverse of the R2_MASKPEN color.
R2_NOTMERGEPEN Pixel is the inverse of the R2_MERGEPEN color.
R2_NOTXORPEN Pixel is the inverse of the R2_XORPEN color.
R2_WHITE Pixel is always 1.
<b>BOOL Polygon( </b>
<i><b> HDC hdc, // handle to device context </b></i>
<i><b> CONST POINT *lpPoints, // pointer to polygon's vertices </b></i>
<i><b> int nCount // count of polygon's vertices </b></i>
<b>); </b>
<b>BOOL PolyPolygon( </b>
<i><b> HDC hdc, // handle to device context </b></i>
<i><b> CONST POINT *lpPoints, // pointer to array of vertices for polygons </b></i>
<i><b> CONST INT *lpPolyCounts, // pointer to array with count of vertices </b></i>
<i><b> int nCount // count of polygons </b></i>
<b>); </b>
<b>BOOL Rectangle( </b>
<i><b> HDC hdc, // handle to device context </b></i>
Hình 4-1 Rectangle
<i><b> HDC hdc, // handle to device context </b></i>
Hình 4-2 RoundRect
<i><b> HDC hDC, // handle to device context </b></i>
<i><b> CONST RECT *lprc, // pointer to rectangle coordinates </b></i>
<i><b> HBRUSH hbr // handle to brush </b></i>
<b>); </b>
<i><b> HDC hDC, // handle to device context </b></i>
<i><b> CONST RECT *lprc, // pointer to structure with rectangle </b></i>
<i><b> HBRUSH hbr // handle to brush </b></i>
<b>); </b>
<i><b> HDC hDC, // handle to device context </b></i>
<i><b> CONST RECT *lprc // pointer to structure with rectangle </b></i>
<b>); </b>
<i><b> HDC hdc, // handle to device context </b></i>
Hình 4-3 Ellipse
<b>BOOL Pie( </b>
<i><b> HDC hdc, // handle to device context </b></i>
<i><b> int nLeftRect, // x-coord of bounding rectangle's upper-left corner </b></i>
<i><b> int nTopRect, // y-coord of bounding rectangle's upper-left corner </b></i>
<i><b> int nRightRect, // x-coord of bounding rectangle's lower-right corner </b></i>
<i><b> int nBottomRect, // y-coord of bounding rectangle's lower-right corner </b></i>
<i><b> int nXRadial1, // x-coord of first radial's endpoint </b></i>
<b>Hình 4-4 Pie </b>
<b>BOOL Chord( </b>
<i><b> HDC hdc, // handle to device context </b></i>
<i><b> int nLeftRect, // x-coord of the upper-left corner of bounding rectangle </b></i>
<i><b> int nTopRect, // y-coord of the upper-left corner of bounding rectangle </b></i>
<i><b> int nRightRect, // x-coord of the lower-right corner of bounding rectangle </b></i>
<i><b> int nBottomRect, // y-coord of the lower-right corner of bounding rectangle </b></i>
<i><b> int nXRadial1, // x-coord of the first radial's endpoint </b></i>
<i><b> int nYRadial1, // y-coord of the first radial's endpoint </b></i>
<i><b> int nXRadial2, // x-coord of the second radial's endpoint </b></i>
Hình 4-5 Chord
<b>int SetPolyFillMode( </b>
<i><b>HDC hdc, </b></i> // handle of device context
<i><b>int iPolyFillMode </b></i> // polygon fill mode
<b>); </b>
<i><b>HDC hdc, </b></i>
<i><b>COLORREF crColor </b></i>
<b>); </b>
<i><b>HDC hdc, </b></i>
<i><b>int iBkMode </b></i>
<b>); </b>
Hình 4-6 – Chế độ tơ màu ALTERNATE và WINDING
HBRUSH hbr;
hbr = GetStockObject(GRAY_BRUSH);
SelectObject(hdc, hbr);
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
HBRUSH hbr;
GetClientRect(hWnd, &rt);
<b>hbr = CreateHatchBrush(HS_BDIAGONAL, RGB(0,0,0xff)); </b>
<b>SelectObject(hdc, hbr); </b>
Ellipse(hdc, rt.right/8, rt.bottom/8, 7*rt.right/8, 7*rt.bottom/8);
EndPaint(hWnd, &ps);
<b>DeleteObject(hbr); </b>
break;
case WM_CREATE:
<b>hbr = CreateHatchBrush(HS_BDIAGONAL, RGB(0,0,0xff)); </b>
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
GetClientRect(hWnd, &rt);
<b>SelectObject(hdc, hbr); </b>
Ellipse(hdc, rt.right/8, rt.bottom/8, 7*rt.right/8, 7*rt.bottom/8);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
<b>DeleteObject(hbr); </b>
<b>HBRUSH CreateSolidBrush( </b>
<i><b> COLORREF crColor // brush color value </b></i>
<b>); </b>
<b>HBRUSH CreateHatchBrush( </b>
<i><b> int fnStyle, // hatch style </b></i>
<i><b> COLORREF clrref // color value </b></i>
<b>); </b>
<b>HBRUSH CreatePatternBrush( </b>
<i><b> HBITMAP hbmp // handle to bitmap </b></i>
<b>); </b>
LONG lbHatch;
} LOGBRUSH;
#define MAX_BRUSHES 30
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
int i;
static nBrushes, nCurBrush;
static HBRUSH ahbr[MAX_BRUSHES];
static TCHAR *aszName[MAX_BRUSHES];
static BYTE acPattern1[] = {
0xff, 0,
0xe7, 0,
0xc3, 0,
0x99, 0,
0x3c, 0,
0x7e, 0,
0xff, 0,
0xff, 0,
};
static BYTE acPattern2[] = {
0x81, 0,
0x82, 0,
0x84, 0,
switch (message)
{
aszName[nBrushes++] = "Hatch HS_FDIAGONAL";
ahbr[nBrushes] = CreateHatchBrush(HS_HORIZONTAL, RGB(0,0,0xff));
aszName[nBrushes++] = "Hatch HS_HORIZONTAL";
ahbr[nBrushes] = CreateHatchBrush(HS_VERTICAL, RGB(0,0,0xff));
aszName[nBrushes++] = "Hatch HS_VERTICAL";
hBitmap = CreateBitmap(8,8,1,1, acPattern1);
ahbr[nBrushes] = CreatePatternBrush(hBitmap);
aszName[nBrushes++] = "Pattern Brush 1";
DeleteObject(hBitmap);
hBitmap = CreateBitmap(8,8,1,1, acPattern2);
ahbr[nBrushes] = CreatePatternBrush(hBitmap);
aszName[nBrushes++] = "Pattern Brush 2";
DeleteObject(hBitmap);
hBitmap = LoadBitmap(hInst, (LPCTSTR)IDB_BITMAP1);
ahbr[nBrushes] = CreatePatternBrush(hBitmap);
hBitmap = LoadBitmap(hInst, (LPCTSTR)IDB_BITMAP2);
ahbr[nBrushes] = CreatePatternBrush(hBitmap);
aszName[nBrushes++] = "RC Pattern Brush 2";
DeleteObject(hBitmap);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
Rectangle(hdc, 180, i*35+10, 600, i*35+39);
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
for (i = 0; i < nBrushes; i++)
DeleteObject(ahbr[i]);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rt);
hpen = CreatePen(PS_SOLID, 16, RGB(0,255,0));
SelectObject(hdc, hpen);
Ellipse(hdc, 0, 0, 4*rt.right/7, 4*rt.bottom/7);
DeleteObject(hpen);
hpen = CreatePen(PS_INSIDEFRAME, 16, RGB(0,255,0));
SelectObject(hdc, hpen);
Ellipse(hdc, 3*rt.right/7, 3*rt.bottom/7, rt.right, rt.bottom);
DeleteObject(hpen);
SelectObject(hdc, GetStockObject(HOLLOW_BRUSH));
hpen = CreatePen(PS_SOLID, 1, RGB(255,0,0));
SelectObject(hdc, hpen);
Ellipse(hdc, 0, 0, 4*rt.right/7, 4*rt.bottom/7);
Ellipse(hdc, 3*rt.right/7, 3*rt.bottom/7, rt.right, rt.bottom);
DeleteObject(hpen);
rt.left = 3*rt.right/7;
rt.top = 3*rt.bottom/7;
DrawText(hdc, szPrompt, strlen(szPrompt), &rt,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hWnd, &ps);
break;
Hình 4-10 – PS_INSIDEFRAME style
<i><b>BOOL StrokePath(HDC hdc); </b></i>
<i><b>BOOL FillPath(HDC hdc); </b></i>
<i><b>BOOL StrokeAndFillPath(HDC hdc ); </b></i>
Hình 4-11 – Minh hoạ Path
// Bezier_Flower.cpp : Defines the entry point for the application.
// Ve va to dung ham PolyBezier, Path
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
void DrawMarker(HDC hdc, POINT pt, int size);
void CreateFlowerPoints(POINT ptCenter, POINT pt, POINT aptFlowers[]);
#define MAX_FLOWERS 100
#define MAX_MARKERS (2*MAX_FLOWERS)
#define MARKER_SIZE 5
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szPrompt[] = TEXT("Bezier Flowers");
static POINT apt[MAX_MARKERS];
static int nMarkers;
int i;
POINT aptFlowers[12];
static HPEN hpen;
static HBRUSH hbrush;
static int nPenWidth = 2;
static COLORREF crPen = RGB(0xff,0,0);
switch (message)
{
case WM_CREATE:
hbrush = CreateSolidBrush(RGB(0, 0xff, 0)); // Green brush
hpen = CreatePen(PS_SOLID, nPenWidth, crPen); // Red pen
break;
case WM_LBUTTONDOWN:
if (nMarkers < MAX_MARKERS)
{
GetClientRect(hWnd, &rt);
DrawText(hdc, szPrompt, strlen(szPrompt), &rt, DT_CENTER);
SelectObject(hdc, hbrush);
SelectObject(hdc, hpen);
for (i = 0; i < nMarkers; i++)
{
DrawMarker(hdc, apt[i], MARKER_SIZE);
if (i%2 == 1)
{
aptFlowers[0] = apt[i-1];
CreateFlowerPoints(apt[i-1], apt[i], aptFlowers);
BeginPath(hdc);
MoveToEx(hdc, apt[i-1].x, apt[i-1].y, NULL);
PolyBezierTo(hdc, aptFlowers, 12);
CloseFigure(hdc);
EndPath(hdc);
StrokeAndFillPath(hdc);
}
}
EndPaint(hWnd, &ps);
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
void CreateFlowerPoints(POINT ptCenter, POINT pt, POINT aptFlowers[])
{
aptFlowers[0] = aptFlowers[1] = pt;
aptFlowers[1].x = 2*ptCenter.x - pt.x;
aptFlowers[2] = ptCenter;
aptFlowers[3].x = aptFlowers[0].x;
aptFlowers[4].x = aptFlowers[1].x;
cout << “Nhap vao hai so nguyen: ”;
cin >> i >> j;
gotoxy(x,y);
cout << “Hello, world\n”;
<b>BOOL ExtTextOut( </b>
<i><b> HDC hdc, // handle to device context </b></i>
<i><b> int X, // x-coordinate of reference point </b></i>
<i><b> int Y, // y-coordinate of reference point </b></i>
<i><b> UINT fuOptions, // text-output options </b></i>
<i><b> CONST RECT *lprc, // optional clipping and/or opaquing rectangle </b></i>
<i><b> LPCTSTR lpString, // points to string </b></i>
<i><b> UINT cbCount, // number of characters in string </b></i>
<i><b> CONST INT *lpDx // pointer to array of intercharacter spacing </b></i>
// values
<b>); </b>
<b>); </b>
<b>Hình 5-1 - TabledTextOut </b>
// TabbedText.cpp : Defines the entry point for the application.
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
#define MAX_FONTS 50
#define dim(a) sizeof(a)/sizeof(a[0])
#define N 2
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
int nItems = dim(aTextData);
int i;
SIZE textSize;
int aTab[N];
LOGFONT lf;
static char *aFaceName[] =
{
"Arial",
"Times New Roman",
"Bookman Old Style",
"BankGothic Lt BT"
};
const int nFaces = sizeof(aFaceName)/sizeof(aFaceName[0]);
static HFONT ahf[MAX_FONTS];
static int nFonts, nCurFont;
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_CREATE:
memset(&lf, 0, sizeof(lf));
for (i = 0; i < nFaces; i++)
{
lf.lfHeight = 32;
lf.lfWidth = 12;
lstrcpy(lf.lfFaceName, aFaceName[i]);
ahf[nFonts++] = CreateFontIndirect(&lf);
}
break;
case WM_RBUTTONDOWN:
nCurFont = ++nCurFont % nFonts;
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
SelectObject(hdc, ahf[nCurFont]);
RECT rt;
GetClientRect(hWnd, &rt);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
<b>int DrawText( </b>
<i><b> HDC hDC, // handle to device context </b></i>
<i><b> LPCTSTR lpString, // pointer to string to draw </b></i>
<i><b> int nCount, // string length, in characters </b></i>
<i><b> LPRECT lpRect, // pointer to struct with formatting dimensions </b></i>
<i><b> UINT uFormat // text-drawing flags </b></i>
<b>); </b>
Hình 5-2 - Minh hoạ DrawText với DT_CENTER
Hình 5-3 - Minh hoạ DrawText với DT_CENTER | DT_WORDBREAK
// Text_WordBreak.cpp :
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
case WM_LBUTTONDOWN:
bWordBreak = !bWordBreak;
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
GetClientRect(hWnd, &rt);
if (bWordBreak)
DrawText(hdc, szHello, strlen(szHello), &rt,
DT_CENTER | DT_WORDBREAK);
else
DrawText(hdc, szHello, strlen(szHello), &rt,
DT_CENTER);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
<i><b> HDC hDC, </b></i> // handle to the device context
<i><b> HBRUSH hBrush, </b></i> // handle to the brush for graying
<i><b> GRAYSTRINGPROC lpOutputFunc, // pointer to the callback function </b></i>
<i><b> LPARAM lpData, </b></i> // pointer to application-defined data
<i><b> int nCount, </b></i> // number of characters to output
<i><b> int X, </b></i> // horizontal position
<i><b> int Y, </b></i> // vertical position
Hình 5-4 – GrayString
// GrayString.cpp :
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[] = "Hello. This is a string created by a call to
GrayString";
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GrayString(hdc, (HBRUSH)GetStockObject(BLACK_BRUSH), NULL,
(LPARAM)szHello, strlen(szHello), 10, 50, 0, 0);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
<b>COLORREF SetTextColor( </b>
<i><b>HDC hdc, </b></i> // handle of device context
<b> </b> <i><b>COLORREF crColor </b></i> // text color
<b> </b> <b>); </b>
<b>UINT SetTextAlign( </b>
<i><b> HDC hdc, </b></i> // handle of device context
<i><b> UINT fMode // text-alignment flag </b></i>
<b> </b> <b>); </b>
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
int i;
static TextAttrData aTextAttrTab[] =
{
"Top Left Black", TA_LEFT | TA_TOP, RGB(0,0,0),
"Top Right Red", TA_RIGHT | TA_TOP, RGB(0xff,0,0),
"Top Center Blue", TA_CENTER | TA_TOP, RGB(0,0,0xff),
"Bottom Left Gray", TA_LEFT | TA_BOTTOM, RGB(0,0,0),
"Bottom Right Green", TA_RIGHT | TA_BOTTOM, RGB(0,0xff,0),
"Bottom Center Blue", TA_CENTER | TA_BOTTOM, RGB(0,0,0xff),
"Baseline Left Black", TA_LEFT | TA_BASELINE, RGB(0,0,0),
"Baseline Center Yellow", TA_CENTER | TA_BASELINE, RGB(0xff,0xff,0),
"Baseline Right Blue", TA_RIGHT | TA_BASELINE, RGB(0xff,0,0),
};
static HBRUSH hbr;
switch (message)
{
case WM_CREATE:
hbr = CreateHatchBrush(HS_BDIAGONAL, RGB(0,0,0xff));
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
POINT pt;
SelectObject(hdc, hbr);
Ellipse(hdc, 50,10, 200, 400);
Ellipse(hdc, 250,10, 400, 400);
Ellipse(hdc, 450,10, 600, 400);
for (i = 0; i < dim(aTextAttrTab); i++)
{
SetTextAlign(hdc, aTextAttrTab[i].nAlign);
SetTextColor(hdc, aTextAttrTab[i].crColor);
pt.x = 100, pt.y = i*40+20;
TextOut(hdc, 100, i*40+20, aTextAttrTab[i].Name,
lstrlen(aTextAttrTab[i].Name));
DrawMarker(hdc, pt, 10);
}
SetBkColor(hdc, RGB(0xc0,0xc0,0xc0));
for (i = 0; i < dim(aTextAttrTab); i++)
{
TextOut(hdc, 500, i*40+20, aTextAttrTab[i].Name,
lstrlen(aTextAttrTab[i].Name));
DrawMarker(hdc, pt, 10);
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
<b>HFONT CreateFont( </b>
<i><b> int nHeight, // logical height of font </b></i>
<i><b> int nWidth, // logical average character width </b></i>
<i><b> int nEscapement, // angle of escapement </b></i>
<i><b> int nOrientation, // base-line orientation angle </b></i>
<i><b> int fnWeight, // font weight </b></i>
<i><b> DWORD fdwItalic, // italic attribute flag </b></i>
<i><b> DWORD fdwUnderline, // underline attribute flag </b></i>
<i><b> DWORD fdwStrikeOut, // strikeout attribute flag </b></i>
<i><b> DWORD fdwCharSet, // character set identifier </b></i>
<i><b> DWORD fdwOutputPrecision, // output precision </b></i>
<i><b> DWORD fdwClipPrecision, // clipping precision </b></i>
<i><b> DWORD fdwQuality, // output quality </b></i>
<i><b> DWORD fdwPitchAndFamily, // pitch and family </b></i>
<i><b> LPCTSTR lpszFace // pointer to typeface name string </b></i>
<b>); </b>
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
TCHAR lfFaceName[LF_FACESIZE];
} LOGFONT;
lfHeight = -MulDiv(PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
ANSI_CHARSET
DEFAULT_QUALITY
DRAFT_QUALITY
PROOF_QUALITY
DEFAULT_PITCH
FIXED_PITCH
VARIABLE_PITCH
<b>); </b>
typedef struct tagSIZE { // siz
LONG cx;
LONG cy;
} SIZE;
<i><b> HDC hdc, // handle to device context </b></i>
<i><b> LPCTSTR lpString, // pointer to text string </b></i>
<i><b> int cbString, // number of characters in string </b></i>
<i><b> LPSIZE lpSize // pointer to structure for string size </b></i>
<b>); </b>
typedef struct tagTEXTMETRIC { // tm
LONG tmHeight;
BCHAR tmLastChar;
BCHAR tmDefaultChar;
BCHAR tmBreakChar;
BYTE tmItalic;
BYTE tmUnderlined;
BYTE tmStruckOut;
BYTE tmPitchAndFamily;
BYTE tmCharSet;
} TEXTMETRIC;
<i><b> HDC hdc, // handle to device context </b></i>
// Font_Create.cpp : Defines the entry point for the application.
//
HFONT MyCreateFont (HDC hdc, char * szFaceName, int nPointSize,
BOOL bBold = FALSE, BOOL bItalic = FALSE)
{
HFONT hFont ;
LOGFONT lf ;
memset(&lf, 0, sizeof(lf));
lf.lfHeight = -MulDiv(nPointSize, GetDeviceCaps(hdc, LOGPIXELSY),
72);
int nPointSize;
BOOL bBold, bItalics;
};
#define MAX_FONTS 20
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
PAINTSTRUCT ps;
HDC hdc;
LOGFONT lf;
static FONTDATA aFontData[] =
{
"Arial size 20", "Arial", 20, FALSE, FALSE,
"Times New Roman Bold size 30", "Times New Roman", 30, TRUE, FALSE,
"Font Việt Nam VNI-Times co 24 nghiêng", "VNI-Times", 24, FALSE, TRUE,
"VNI-Bodon-Poster co 24 maäp", "VNI-Bodon-Poster", 24, TRUE, FALSE,
"VNI-Hobo co 40 maäp", "VNI-Hobo", 40, TRUE, FALSE
};
const int nFonts = sizeof(aFontData)/sizeof(aFontData[0]);
static HFONT ahf[MAX_FONTS];
switch (message)
{
case WM_CREATE:
memset(&lf, 0, sizeof(lf));
hdc = GetDC(hWnd);
for (i = 0; i < nFonts; i++)
ahf[i] = MyCreateFont(hdc, aFontData[i].szFaceName,
aFontData[i].nPointSize, aFontData[i].bBold,
aFontData[i].bItalics);
ReleaseDC(hWnd, hdc);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
for (i = 0; i < nFonts; i++)
{
SelectObject(hdc, ahf[i]);
TextOut(hdc, 30, 50*(i+1), aFontData[i].szPrompt,
lstrlen(aFontData[i].szPrompt));
Hình 5-7 – Font và Path
// Font_Path.cpp
int nPenWidth = 2;
COLORREF crPen = RGB(0xff,0,0);
switch (message)
{
case WM_CREATE:
memset(&lf, 0, sizeof(lf));
lf.lfHeight = 120;
lf.lfWidth = 0;
lstrcpy(lf.lfFaceName, "Times New Roman");
hfont = CreateFontIndirect(&lf);
hbrush = CreateSolidBrush(RGB(0, 0xff, 0)); // Green brush
hpen = CreatePen(PS_SOLID, nPenWidth, crPen); // Red pen
crText = RGB(0xc0, 0xc0, 0xc0); // Gray text
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
GetClientRect(hWnd, &rt);
rt.top += 10;
SelectObject(hdc, hfont);
SelectObject(hdc, hbrush);
SelectObject(hdc, hpen);
BeginPath(hdc);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
EndPath(hdc);
StrokeAndFillPath(hdc);
SetBkMode(hdc, TRANSPARENT);
BeginPath(hdc);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER | DT_VCENTER |
DT_SINGLELINE);
EndPath(hdc);
StrokeAndFillPath(hdc);
SetTextColor(hdc, crText);
SetTimer(hWnd, ID_MOVE_TIMER, 10, NULL);
SetTimer(hWnd, ID_CHANGECOLOR_TIMER, 1000, NULL);
Hình 6-2 Cửa sổ chương trình
// bounce.cpp : Defines the entry point for the application.
//
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
enum {ID_MOVE_TIMER = 1, ID_CHANGECOLOR_TIMER = 2};
SetTimer(hWnd, ID_MOVE_TIMER, 10, NULL);
SetTimer(hWnd, ID_CHANGECOLOR_TIMER, 1000, NULL);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd,
(DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_TIMER:
switch(wParam)
{
case ID_MOVE_TIMER:
RECT rClient, r;
GetClientRect(hWnd, &rClient);
r.left = x - rBall - abs(dx);
r.right = x + rBall + abs(dx);
r.top = y - rBall - abs(dy);
r.bottom = y + rBall + abs(dy);
x += dx;
y += dy;
if (x + rBall > rClient.right && dx > 0) dx = -dx;
if (x - rBall < 0 && dx < 0) dx = -dx;
if (y + rBall > rClient.bottom && dy > 0) dy = -dy;
if (y - rBall < 0 && dy < 0) dy = -dy;
InvalidateRect(hWnd, &r, TRUE);
break;
case ID_CHANGECOLOR_TIMER:
++nCrIdx %= nColors;
break;
KillTimer(hWnd, ID_CHANGECOLOR_TIMER);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
SetTimer(hWnd, ID_MOVE_TIMER, 10, TimerProc);
SetTimer(hWnd, ID_CHANGECOLOR_TIMER, 1000, TimerProc);
// bounce.cpp : Defines the entry point for the application.
//
enum {ID_MOVE_TIMER = 1, ID_CHANGECOLOR_TIMER = 2};
VOID CALLBACK TimerProc (HWND hWnd, UINT message, UINT wParam, DWORD lParam)
{
static int x = 40,y = 50,rBall=10,dx=5,dy=5, nCrIdx;
static COLORREF aColorTab [] = {RGB(0xff,0,0), RGB(0,0xff,0),
RGB(0,0,0xff), RGB(0,0,0), RGB(0xff,0xff,0xff),RGB(0xc0,0xc0,0xc0)};
static int nColors = sizeof(aColorTab)/sizeof(aColorTab[0]);
switch(wParam)
{
case ID_MOVE_TIMER:
RECT rClient, r;
if (y - rBall < 0 && dy < 0) dy = -dy;
SelectObject(hdc, hbr);
SelectObject(hdc, GetStockObject(BLACK_PEN));
Ellipse(hdc, x - rBall, y - rBall, x + rBall, y + rBall);
DeleteObject(hbr);
ReleaseDC(hWnd, hdc);
break;
case ID_CHANGECOLOR_TIMER:
}
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_CREATE:
SetTimer(hWnd, ID_MOVE_TIMER, 10, TimerProc);
SetTimer(hWnd, ID_CHANGECOLOR_TIMER, 1000, TimerProc);
break;
case WM_COMMAND:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
KillTimer(hWnd, ID_MOVE_TIMER);
KillTimer(hWnd, ID_CHANGECOLOR_TIMER);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//
struct BALL
{
int x,y,r,dx,dy;
COLORREF crColor;
};
BALL CreateNewBall()
{
BALL b;
b.x = 0, b.y = 0, b.r = 10, b.dx = b.dy = 5;
return b;
};
BALL CreateNewBall(int x, int y, int r, int dx, int dy, COLORREF color)
{
BALL b;
b.x = x, b.y = y, b.r = r, b.dx = dx; b.dy = dy;
b.crColor = color;
return b;
};
const int MAX_BALLS = 100;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
static BALL aBalls[MAX_BALLS];
static int nBalls;
static COLORREF aColorTab [] = {RGB(0xff,0,0), RGB(0,0xff,0),
RGB(0,0,0xff), RGB(0,0,0), RGB(0xff,0xff,0xff),RGB(0xc0,0xc0,0xc0)};
static int nColors = sizeof(aColorTab)/sizeof(aColorTab[0]);
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
RECT rt;
switch (message)
{
case WM_CREATE:
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_CHAR:
switch(toupper(TCHAR(wParam)))
{
case 'N':
GetClientRect(hWnd, &rt);
aBalls[nBalls] = CreateNewBall(rand()%rt.right,
rand()%rt.bottom, 10, 5, 5, aColorTab[nBalls%nColors]);
SetTimer(hWnd, nBalls++, 10, NULL);
break;
case 'R':
if (nBalls > 0)
KillTimer(hWnd, --nBalls);
InvalidateRect(hWnd, NULL, TRUE);
break;
}
break;
case WM_TIMER:
RECT rClient, r;
BALL *pb;
pb = &aBalls[wParam];
GetClientRect(hWnd, &rClient);
r.left = pb->x - pb->r - abs(pb->dx);
r.right = pb->x + pb->r + abs(pb->dx);
r.top = pb->y - pb->r - abs(pb->dy);
r.bottom = pb->y + pb->r + abs(pb->dy);
pb->x += pb->dx;
pb->y += pb->dy;
if (pb->x + pb->r > rClient.right && pb->dx > 0) pb->dx = -pb->dx;
if (pb->x - pb->r < 0 && pb->dx < 0) pb->dx = -pb->dx;
if (pb->y + pb->r > rClient.bottom && pb->dy > 0) pb->dy = -pb->dy;
if (pb->y - pb->r < 0 && pb->dy < 0) pb->dy = -pb->dy;
InvalidateRect(hWnd, &r, TRUE);
break;
case WM_PAINT:
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
VOID VeVongTron(HDC hdc, int tx, int ty, int bk, HBRUSH hbr)
{
SelectObject(hdc, hbr);
Ellipse(hdc, tx-bk, ty-bk, tx+bk, ty+bk);
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
const float PI = 3.1415926F;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
static int nBkQuiDao = 160, nBkMatTroi = 20, nBkQuaDat = 8;
static COLORREF crMatTroi = RGB(255,0,0), crQuaDat = RGB(0,255,0);
static HBRUSH hbrMatTroi, hbrQuaDat;
// static int txQuaDat, tyQuaDat;
static HPEN hpenQuiDao;
static float fGoc = -PI/4, fStep = 0.1f;
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_TIMER:
hdc = GetDC(hWnd);
SetROP2(hdc, R2_NOTXORPEN);
VeVongTron(hdc, rt.right/2 + int(nBkQuiDao*cos(fGoc)),
rt.bottom/2 + int(nBkQuiDao*sin(fGoc)), nBkQuaDat, hbrQuaDat);
fGoc -= fStep;
VeVongTron(hdc, rt.right/2 + int(nBkQuiDao*cos(fGoc)),
rt.bottom/2 + int(nBkQuiDao*sin(fGoc)), nBkQuaDat, hbrQuaDat);
ReleaseDC(hWnd, hdc);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
GetClientRect(hWnd, &rt);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
VeDuongTron(hdc, rt.right/2, rt.bottom/2, nBkQuiDao, hpenQuiDao);
SelectObject(hdc, GetStockObject(BLACK_PEN));
VeVongTron(hdc, rt.right/2, rt.bottom/2, nBkMatTroi, hbrMatTroi);
SetROP2(hdc, R2_NOTXORPEN);
VeVongTron(hdc, rt.right/2 + int(nBkQuiDao*cos(fGoc)),
<b>HWND SetCapture( </b>
<i><b> HWND hWnd // handle of window to receive mouse capture </b></i>
<b>); </b>
<b>BOOL ReleaseCapture(VOID) </b>
small.ico
ObjectDrag.ico
resource.h
// ObjectDrag.cpp : Defines the entry point for the application.
// ...
bool IsInsideEllipse(int x1, int y1, int x2, int y2, int x, int y)
{
double a = (double(x2)-x1)/2, b = (double(y2)-y1)/2;
if (!a || !b) return false;
double xx = x - (double(x1)+x2)/2, yy = y - (double(y1)+y2)/2;
double xr = xx/a, yr = yy/b;
return xr*xr+yr*yr <= 1;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
static HCURSOR hCursorMove;
static x1,y1,x2,y2, px, py;
static HBRUSH hbr;
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_CREATE:
RECT rt;
GetClientRect(hWnd, &rt);
x1 = rt.right/4; x2 = 3*rt.right/4;
y1 = rt.bottom/4; y2 = 3*rt.bottom/4;
HBITMAP hBitmap;
hBitmap = LoadBitmap(hInst, (LPCTSTR)IDB_HEART);
hbr = CreatePatternBrush(hBitmap);
DeleteObject(hBitmap);
hCursorMove = LoadCursor(NULL, IDC_SIZEALL);
break;
case WM_LBUTTONDOWN:
int x, y;
px = x = LOWORD(lParam);
py = y = HIWORD(lParam);
{
SetCursor(hCursorMove);
if (GetCapture() == hWnd)
{
int dx = x-px, dy = y-py;
x1 += dx; y1 += dy;
x2 += dx; y2 += dy;
px = x;
py = y;
InvalidateRect(hWnd, NULL, TRUE);
}
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
SelectObject(hdc, hbr);
Ellipse(hdc,x1,y1,x2,y2);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
small.ico
ObjectDrag.ico
resource.h
ObjectDrag.rc
StdAfx.h
StdAfx.cpp
//////////////////////////////////////////////////////////////////
bool IsInsideEllipse(int x1, int y1, int x2, int y2, int x, int y)
{
double a = (double(x2)-x1)/2, b = (double(y2)-y1)/2;
if (!a || !b) return false;
double xx = x - (double(x1)+x2)/2, yy = y - (double(y1)+y2)/2;
double xr = xx/a, yr = yy/b;
return xr*xr+yr*yr <= 1;
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
static int x1,y1,x2,y2,xc,yc,px,py;
static HBRUSH hbr;
static HCURSOR hCursorMove;
static HPEN hPenDot;
int dx, dy;
RECT rt;
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_CREATE:
GetClientRect(hWnd, &rt);
x1 = rt.right/4; x2 = 3*rt.right/4;
y1 = rt.bottom/4; y2 = 3*rt.bottom/4;
hbr = CreateHatchBrush(HS_DIAGCROSS, RGB(255,0,0));
hCursorMove = LoadCursor(NULL, IDC_SIZEALL);
hPenDot = CreatePen(PS_DOT, 1, RGB(0,0,255));
break;
case WM_COMMAND:
case WM_LBUTTONDOWN:
xc = LOWORD(lParam); yc = HIWORD(lParam);
if (IsInsideEllipse(x1,y1,x2,y2,xc,yc))
{
hdc = GetDC(hWnd);
SelectObject(hdc,hPenDot);
SetROP2(hdc, R2_NOTXORPEN);
Ellipse(hdc,x1,y1,x2,y2);
SetCursor(hCursorMove);
SetCapture(hWnd);
}
break;
case WM_MOUSEMOVE:
if (GetCapture() == hWnd)
{
hdc = GetDC(hWnd);
SelectObject(hdc,hPenDot);
SetROP2(hdc, R2_NOTXORPEN);
Ellipse(hdc,x1,y1,x2,y2);
px = xc; py = yc;
xc = LOWORD(lParam); yc = HIWORD(lParam);
dx = xc-px, dy = yc - py;
x1 += dx, x2 += dx,
y1 += dy, y2 += dy;
Ellipse(hdc,x1,y1,x2,y2);
}
break;
case WM_LBUTTONUP:
if (GetCapture() == hWnd)
{
ReleaseCapture();
InvalidateRect(hWnd, NULL, TRUE);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rt);
Hình 7-8 Cửa sổ chương trình sau khi di chuyển ba hình đầu và vẽ thêm 4 hình khác.
// ObjectDrag.cpp : Defines the entry point for the application.
//...
class CEllipse
{
int x1,y1,x2,y2;
COLORREF crColor;
int hatch;
public:
CEllipse(){Set(0,0,0,0); SetColor(RGB(0,0,255)); SetHatch(HS_DIAGCROSS);}
CEllipse(int _x1, int _y1, int _x2, int _y2) {
};
void CEllipse::Draw(HDC hdc)
{
HBRUSH hbr;
hbr = CreateHatchBrush(hatch, crColor);
Ellipse(hdc,x1,y1,x2,y2);
DeleteObject(hbr);
}
bool CEllipse::IsInside(int x, int y)
{
double a = (double(x2)-x1)/2, b = (double(y2)-y1)/2;
if (!a || !b) return false;
double xx = x - (double(x1)+x2)/2, yy = y - (double(y1)+y2)/2;
double xr = xx/a, yr = yy/b;
return xr*xr+yr*yr <= 1;
}
void CEllipse::Translate(int dx, int dy)
{
x1 += dx; y1 += dy;
x2 += dx; y2 += dy;
}
int FindEllipse(CEllipse ae[], int n, int x, int y)
{
for (int i = n-1; i >= 0; i--)
return i;
return -1;
}
//////////////////////////////////////////////////////////
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
static COLORREF aCrTab[] =
{
RGB(0,255,0), RGB(0, 255,255),RGB(0,0,0), RGB(255,0,0), RGB(0,0,255),
RGB(255,255,0),
};
static int aHatch[] =
{
HS_HORIZONTAL,
HS_VERTICAL,
HS_FDIAGONAL,
HS_BDIAGONAL,
HS_CROSS,
HS_DIAGCROSS
int dx, dy, i;
static int curColor, curHatch = 5;
static INT flag = DRAW, nEllipse,nCur = -1;
RECT rt;
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_CREATE:
GetClientRect(hWnd, &rt);
hCursorMove = LoadCursor(NULL, IDC_SIZEALL);
hCursorCross = LoadCursor(NULL, IDC_CROSS);
hPenDot = CreatePen(PS_DOT, 1, RGB(0,0,255));
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_LBUTTONDOWN:
xc = LOWORD(lParam); yc = HIWORD(lParam);
if ((nCur = FindEllipse(ae, nEllipse, xc, yc)) >= 0)
{
flag = MOVE;
hdc = GetDC(hWnd);
SelectObject(hdc,hPenDot);
else if (nEllipse < MAX_ELLIPSE)// DRAW
{
flag = DRAW;
ae[nEllipse].Set(xc,yc,xc,yc,aCrTab[curColor],aHatch[curHatch]);
hdc = GetDC(hWnd);
SetROP2(hdc, R2_NOTXORPEN);
ae[nEllipse].Draw(hdc);
SetCursor(hCursorCross);
SetCapture(hWnd);
nEllipse++;
}
else
flag = -1;
break;
case WM_MOUSEMOVE:
if (GetCapture() == hWnd)
{
if (flag == MOVE)
{
hdc = GetDC(hWnd);
SelectObject(hdc,hPenDot);
SetROP2(hdc, R2_NOTXORPEN);
ae[nCur].Draw(hdc);
px = xc; py = yc;
xc = LOWORD(lParam); yc = HIWORD(lParam);
dx = xc-px, dy = yc - py;
{
ReleaseCapture();
InvalidateRect(hWnd, NULL, TRUE);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rt);
for (i = 0; i < nEllipse; i++)
ae[i].Draw(hdc);
EndPaint(hWnd, &ps);
wsprintf(buf, "Number of Ellipses: %d", nEllipse);
DrawText(hdc, buf, lstrlen(buf), &rt, DT_CENTER);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
IDI_APPLICATION IDI_HAND
IDI_QUESTION IDI_EXCLAMATION
IDI_ASTERISK IDI_WINLOGO
IDI_WARNING IDI_EXCLAMATION
IDI_ERROR IDI_INFORMATION
IDI_ASTERISK
IDI_SCROLL ICON DISCARDABLE "Scroll.ICO"
IDI_SMALL ICON DISCARDABLE "SMALL.ICO"
<b>HICON LoadIcon( </b>
<i><b> HINSTANCE hInstance, // handle to application instance </b></i>
<i><b> LPCTSTR lpIconName // icon-name string or icon resource </b></i>
// identifier
<b>); </b>
<i><b> HDC hDC, // handle to device context </b></i>
<i><b> int X, // x-coordinate of upper-left corner </b></i>
<i><b> int Y, // y-coordinate of upper-left corner </b></i>
<i><b> HICON hIcon // handle to icon to draw </b></i>
<b>); </b>
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SCROLL);
HICON hIcon2 = LoadIcon(NULL, IDI_APPLICATION);
<i><b> int nIndex // system metric or configuration setting to retrieve </b></i>
<b>);</b>
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
TCHAR szPrompt[] = "Standard Icons";
static ICONDATA aIconTab[] =
{
"IDI_APPLICATION", IDI_APPLICATION,
"IDI_ASTERISK", IDI_ASTERISK,
"IDI_ERROR", IDI_ERROR,
"IDI_EXCLAMATION", IDI_EXCLAMATION,
"IDI_HAND", IDI_HAND,
"IDI_INFORMATION", IDI_INFORMATION,
"IDI_QUESTION", IDI_QUESTION,
"IDI_WARNING", IDI_WARNING,
"IDI_WINLOGO", IDI_WINLOGO
};
int x, y, i;
switch (message)
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
int cxIcon, cyIcon;
GetClientRect(hWnd, &rt);
DrawText(hdc, szPrompt, strlen(szPrompt), &rt, DT_CENTER);
HICON hIcon;
hIcon = LoadIcon(NULL, (LPCTSTR)IDI_APPLICATION);
cxIcon = GetSystemMetrics(SM_CXICON);
cyIcon = GetSystemMetrics(SM_CYICON);
y = 20;
SetTextAlign(hdc, TA_CENTER);
for (i = 0, x = 70; i < dim(aIconTab); i++, x += XSTEP)
{
if (x > rt.right - 50)
x = 70, y += YSTEP;
DrawIcon(hdc, x, y, LoadIcon(NULL, aIconTab[i].iconId));
TextOut(hdc, x+cxIcon/2, y+40, aIconTab[i].szName,
Hình 8-4 Con trỏ chuẩn
<b>HCURSOR LoadCursor( </b>
<i><b> HINSTANCE hInstance, // handle to application instance </b></i>
<i><b> LPCTSTR lpCursorName // name string or cursor resource identifier </b></i>
<b>); </b>
<i><b> BOOL bShow // cursor visibility flag </b></i>
<b>); </b>
<i><b> HCURSOR hCursor // handle to cursor </b></i>
<b>); </b>
SetCursor(LoadCursor(NULL, IDC_WAIT));
IDC_HELLO ACCELERATORS MOVEABLE PURE
BEGIN
"/", IDM_ABOUT, ASCII, ALT, NOINVERT
"?", IDM_ABOUT, ASCII, ALT, NOINVERT
"A", ID_LUACHON_TIENGANH, VIRTKEY, ALT, NOINVERT
"C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
"N", ID_FILE_NEW, VIRTKEY, CONTROL, NOINVERT
"O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
"S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT
"V", ID_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT
"V", ID_OPTION_VIETNAMESE, VIRTKEY, ALT, NOINVERT
"X", ID_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT
END
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_HELLO, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_HELLO);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
IDC_MENU MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&Open ...\tCtrl+O", ID_FILE_OPEN
MENUITEM "&Save\tCtrl+S", ID_FILE_SAVE
MENUITEM "Save &As ...", ID_FILE_SAVEAS
MENUITEM "E&xit", IDM_EXIT
END
POPUP "&Help"
BEGIN
MENUITEM "&About ...", IDM_ABOUT
END
MENUITEM "Quit !", ID_QUIT
MENUITEM "BreakCol", 65535, MENUBREAK
MENUITEM "Break ?", 65535
END
POPUP text [, optionlist]
BEGIN
MENUITEM text, result-code [optionlist]
END
POPUP …
BEGIN
MENUITEM "&About ...", IDM_ABOUT
END
CHECKED
GRAYED
INACTIVE
MENUBREAK – toplevel menu
MENUBARBREAK – popup menu
struct BALL
{
b.crColor = color;
return b;
};
const int MAX_BALLS = 100;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
TCHAR szHello[MAX_LOADSTRING];
static BALL aBalls[MAX_BALLS];
static int nBalls;
static COLORREF aColorTab [] = {RGB(0xff,0,0), RGB(0,0xff,0),
RGB(0,0,0xff), RGB(0,0,0), RGB(0xff,0xff,0xff),RGB(0xc0,0xc0,0xc0)};
static int nColors = sizeof(aColorTab)/sizeof(aColorTab[0]);
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
RECT rt;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case ID_FILE_NEWBALL:
GetClientRect(hWnd, &rt);
aBalls[nBalls] = CreateNewBall(rand()%rt.right,
SetTimer(hWnd, nBalls++, 10, NULL);
break;
case ID_FILE_REMOVEBALL:
if (nBalls > 0)
KillTimer(hWnd, --nBalls);
InvalidateRect(hWnd, NULL, TRUE);
break;
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
r.bottom = pb->y + pb->r + abs(pb->dy);
pb->x += pb->dx;
pb->y += pb->dy;
if (pb->x + pb->r > rClient.right && pb->dx > 0) pb->dx = -pb->dx;
if (pb->x - pb->r < 0 && pb->dx < 0) pb->dx = -pb->dx;
if (pb->y + pb->r > rClient.bottom && pb->dy > 0) pb->dy = -pb->dy;
if (pb->y - pb->r < 0 && pb->dy < 0) pb->dy = -pb->dy;
InvalidateRect(hWnd, &r, TRUE);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
int i;
GetClientRect(hWnd, &rt);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
HBRUSH hbr;
for (i = 0; i < nBalls; i++)
{
hbr = CreateSolidBrush(aBalls[i].crColor);
SelectObject(hdc, hbr);
Ellipse(hdc, aBalls[i].x - aBalls[i].r, aBalls[i].y -
aBalls[i].r, aBalls[i].x + aBalls[i].r, aBalls[i].y + aBalls[i].r);
DeleteObject(hbr);
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Hình 8-6 Menu với checkmark
// Trich doan resource.h
#define ID_BRUSHCOLOR_WHITE 32771
#define ID_BRUSHCOLOR_RED 32772
#define ID_BRUSHCOLOR_BLUE 32773
#define ID_BRUSHCOLOR_GREEN 32774
#define ID_BRUSHCOLOR_LTGRAY 32775
#define ID_BRUSHCOLOR_GRAY 32776
#define ID_BRUSHCOLOR_BLACK 32777
// Ellipse.cpp : Defines the entry point for the application.
#define MAX_MARKERS 100
#define MARKER_SIZE 5
void DrawMarker(HDC hdc, POINT pt, int size);
switch (message)
{
case WM_COMMAND:
hMenu = GetMenu(hWnd);
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case ID_BRUSHCOLOR_WHITE:
case ID_BRUSHCOLOR_RED:
case ID_BRUSHCOLOR_BLUE:
case ID_BRUSHCOLOR_GREEN:
case ID_BRUSHCOLOR_LTGRAY:
case ID_BRUSHCOLOR_GRAY:
case ID_BRUSHCOLOR_BLACK:
CheckMenuItem (hMenu, nBrushColor, MF_UNCHECKED);
nBrushColor = LOWORD (wParam) ;
CheckMenuItem (hMenu, nBrushColor, MF_CHECKED) ;
InvalidateRect (hWnd, NULL, TRUE) ;
return 0 ;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_LBUTTONDOWN:
if (nMarkers <= MAX_MARKERS)
{
apt[nMarkers].x = LOWORD(lParam);
apt[nMarkers].y = HIWORD(lParam);
nMarkers++;
InvalidateRect(hWnd, NULL, TRUE);
}
break;
case WM_RBUTTONDOWN:
nMarkers = 0;
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
hbr = CreateHatchBrush(HS_BDIAGONAL,
aColorTab[nBrushColor - ID_BRUSHCOLOR_WHITE]);
RECT rt;
GetClientRect(hWnd, &rt);
SelectObject(hdc, hbr);
Ellipse(hdc, apt[i-1].x, apt[i-1].y,
apt[i].x, apt[i].y);
}
}
DeleteObject(hpen);
DeleteObject(hbr);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
<b>CreateBitmap</b> Creates a bitmap.
<b>CreateBitmapIndirect</b> Creates a bitmap.
<b>CreateCompatibleBitmap</b> Creates a bitmap compatible with a device.
<b>CreateDIBitmap</b> Creates a device-dependent bitmap (DDB) from a DIB.
<b>CreateDIBSection</b> Creates a DIB that applications can write to directly.
<b>ExtFloodFill</b> Fills an area of the display surface with the current brush.
<b>GetBitmapDimensionEx</b> Gets the dimensions of a bitmap.
<b>GetDIBColorTable</b> Retrieves RGB color values from a DIB section bitmap.
<b>GetDIBits</b> Copies a bitmap into a buffer.
<b>GetPixel</b> Gets the RGB color value of the pixel at a given coordinate.
<b>GetStretchBltMode</b> Gets the current stretching mode.
<b>GradientFill</b> Fills rectangle and triangle structures.
<b>LoadBitmap</b> Loads a bitmap from a module's executable file.
<b>MaskBlt</b> Combines the color data in the source and destination bitmaps.
<b>PlgBlt</b> Performs a bit-block transfer.
<b>SetBitmapDimensionEx</b> Sets the preferred dimensions to a bitmap.
<b>SetDIBColorTable</b> Sets RGB values in a DIB.
<b>SetDIBits</b> Sets the pixels in a bitmap using color data from a DIB.
<b>SetDIBitsToDevice</b> Sets the pixels in a rectangle using color data from a DIB.
<b>SetPixel</b> Sets the color for a pixel.
<b>SetPixelV</b> Sets a pixel to the best approximation of a color.
<b>SetStretchBltMode</b> Sets the bitmap stretching mode.
<b>StretchBlt</b> Copies a bitmap and stretches or compresses it.
<b>StretchDIBits</b> Copies the color data in a DIB.
<b>HBITMAP CreateCompatibleBitmap( </b>
<i><b> HDC </b>hdc</i><b>, // handle to DC </b>
<i><b> int </b>nWidth</i><b>, // width of bitmap, in pixels </b>
<b>); </b>
<i><b> int </b>nHeightDest</i><b>, // height of destination rectangle </b>
<i><b> int </b>nXOriginSrc</i><b>, // x-coord of source upper-left corner </b>
<i><b> int </b>nYOriginSrc</i><b>, // y-coord of source upper-left corner </b>
<i><b> int </b>nWidthSrc</i><b>, // width of source rectangle </b>
<i><b> int </b>nHeightSrc</i><b>, // height of source rectangle </b>
<i><b> DWORD </b>dwRop</i> // raster operation code
<b>); </b>
Campanula.BMP CampanulaSM.BMP
ShowBitmap.ICO SMALL.ICO
Hình 8-7 Cửa sổ client của chương trình
Hình 8-8 Hộp hội thoại của chương trình
#include "resource.h"
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_SHOWBITMAP ICON DISCARDABLE "ShowBitmap.ICO"
IDI_SMALL ICON DISCARDABLE "SMALL.ICO"
/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_FLOWER BITMAP DISCARDABLE "Campanula.BMP"
IDB_FLOWER_SM BITMAP DISCARDABLE "CampanulaSM.BMP"
// ShowBitmap.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
// ...
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
//...
// DrawBitmap
void DrawBitmap(HDC hdc, HBITMAP hBitmap, int xStart, int yStart)
{
BITMAP bmp;
HDC hdcMem;
hdcMem = CreateCompatibleDC(hdc);
SelectObject(hdcMem, hBitmap);
GetObject(hBitmap, sizeof(bmp), (LPVOID) &bmp);
BitBlt(hdc, xStart, yStart, bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0,
SRCCOPY);
DeleteDC(hdcMem);
}
//
{
case WM_CREATE:
hBitmap = LoadBitmap(hInst, (LPCTSTR)IDB_FLOWER);
BITMAP bmp;
GetObject(hBitmap, sizeof(bmp), (LPVOID) &bmp);
sizeDoc.cx = bmp.bmWidth;
sizeDoc.cy = bmp.bmHeight;
RECT rtWnd, rtClient;
GetWindowRect(hWnd, &rtWnd);
GetClientRect(hWnd, &rtClient);
MoveWindow(hWnd, 0, 0,
sizeDoc.cx+rtWnd.right-rtWnd.left-rtClient.right,
sizeDoc.cy+rtWnd.bottom-rtWnd.top-rtClient.bottom, TRUE);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
DrawBitmap(hdc, hBitmap, 0, 0);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
CampanulaSM.BMP ShowBitmap.ICO SMALL.ICO
StdAfx.h StdAfx.cpp
resource.h ShowBitmap.rc
ShowBitmap.h ShowBitmap.cpp
Hình 8-9 Cửa sổ client của chương trình
HDC hdcMem;
hdcMem = CreateCompatibleDC(hdc);
SelectObject(hdcMem, hBitmap);
GetObject(hBitmap, sizeof(bmp), (LPVOID) &bmp);
BitBlt(hdc, xStart, yStart, bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0,
SRCCOPY);
DeleteDC(hdcMem);
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
static SIZE sizeBmp;
static HBITMAP hBitmap;
static int nGap = 1;
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_CREATE:
hBitmap = LoadBitmap(hInst, (LPCTSTR)IDB_FLOWER_SM);
BITMAP bmp;
GetObject(hBitmap, sizeof(bmp), (LPVOID) &bmp);
sizeBmp.cx = bmp.bmWidth;
sizeBmp.cy = bmp.bmHeight;
break;
case WM_SIZE:
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
RECT rt;
int i, nx, ny;
SIZE size;
hdc = BeginPaint(hWnd, &ps);
DrawBitmap(hdc, hBitmap, 0, 0);
GetClientRect(hWnd, &rt);
size = sizeBmp;
nx = (rt.right-1)/size.cx+1;
ny = (rt.bottom-1)/size.cy+1;
for (i = 1; i < nx; i++)
BitBlt(hdc, size.cx*i, 0, sizeBmp.cx, sizeBmp.cy, hdc, 0, 0,
SRCCOPY);
for (i = 1; i < ny; i++)
BitBlt(hdc, 0, size.cy*i, rt.right, sizeBmp.cy, hdc, 0, 0,
SRCCOPY);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
<b>HMENU LoadMenu( </b>
<i><b> HINSTANCE hInstance, // handle to application instance </b></i>
<i><b> LPCTSTR lpMenuName // menu name string or menu-resource </b></i>
// identifier
<b>); </b>
<i><b> HWND hWnd, // handle to window </b></i>
<i><b> HMENU hMenu // handle to menu </b></i>
<b>); </b>
<i><b> HWND hWnd // handle to window with menu bar to redraw </b></i>
<b>); </b>
<b>BOOL AppendMenu( </b>
<i><b> HMENU </b>hMenu</i><b>, // handle to menu </b>
<i><b> UINT </b>uFlags</i><b>, // menu-item options </b>
<i><b> UINT_PTR </b>uIDNewItem</i><b>, // identifier, menu, or submenu </b>
<i><b> LPCTSTR </b>lpNewItem // menu-item content </i>
<b>); </b>
#define IDD_ABOUTBOX 103
#define IDS_APP_TITLE 103
#define IDM_ABOUT 104
#define IDM_EXIT 105
#define IDS_HELLO 106
#define IDI_HELLO 107
#define IDS_HELLOVN 107
#define IDI_SMALL 108
#define IDC_HELLO 109
#define IDC_HELLOVN 110
#define IDR_MAINFRAME 128
#define ID_FILE_NEW 32771
#define ID_FILE_OPEN 32772
#define ID_FILE_SAVE 32773
#define ID_FILE_PRINT 32774
#define ID_EDIT_COPY 32775
#define ID_EDIT_CUT 32776
#define ID_EDIT_PASTE 32777
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 132
#define _APS_NEXT_COMMAND_VALUE 32780
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif
<b>// Hello.rc </b>
#include "resource.h"
#include "windows.h"
/////////////////////////////////////////////////////////////////////////////
//
POPUP "&File"
BEGIN
MENUITEM "&New\tCtrl+N", ID_FILE_NEW
MENUITEM "&Print", ID_FILE_PRINT
MENUITEM "E&xit", IDM_EXIT
END
POPUP "&Edit"
BEGIN
MENUITEM "&Copy\tCtrl+C", ID_EDIT_COPY
MENUITEM "Cut\tCtrl+X", ID_EDIT_CUT
MENUITEM "&Paste\tCtrl+V", ID_EDIT_PASTE
END
POPUP "&Option"
BEGIN
MENUITEM "&Vietnamese\tAlt+V", ID_OPTION_VIETNAMESE
END
POPUP "&Help"
BEGIN
MENUITEM "&About ...", IDM_ABOUT
END
END
IDC_HELLOVN MENU DISCARDABLE
BEGIN
POPUP "&Ho So"
BEGIN
MENUITEM "Ho so &Moi\tCtrl+N", ID_FILE_NEW
MENUITEM "Mo &Ho so\tCtrol+O", ID_FILE_OPEN
MENUITEM "&Luu Ho so\tCtrl+S", ID_FILE_SAVE
MENUITEM SEPARATOR
MENUITEM "&In Ho so", ID_FILE_PRINT
MENUITEM "&Thoat", IDM_EXIT
END
POPUP "&Soan Thao"
BEGIN
//
IDC_HELLO ACCELERATORS MOVEABLE PURE
BEGIN
"/", IDM_ABOUT, ASCII, ALT, NOINVERT
"?", IDM_ABOUT, ASCII, ALT, NOINVERT
"A", ID_LUACHON_TIENGANH, VIRTKEY, ALT, NOINVERT
"C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
"N", ID_FILE_NEW, VIRTKEY, CONTROL, NOINVERT
"O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
"S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_APP_TITLE "Hello"
IDS_HELLO "Hello World! Press Alt + V to change to Vietnamese"
IDS_HELLOVN "Xin chao! Bam Alt + A de chuyen sang tieng Anh"
IDC_HELLO "HELLO"
IDC_HELLOVN "HELLOVN"
END
// Hello.cpp : Defines the entry point for the application.
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
HMENU hMenu;
hMenu = LoadMenu(hInst, (LPCSTR)IDC_HELLOVN);
SetMenu(hWnd, hMenu);
DrawMenuBar(hWnd);
bVietNamese = TRUE;
InvalidateRect(hWnd, NULL, TRUE);
break;
case ID_LUACHON_TIENGANH:
hMenu = LoadMenu(hInst, (LPCSTR)IDC_HELLO);
SetMenu(hWnd, hMenu);
DrawMenuBar(hWnd);
bVietNamese = FALSE;
InvalidateRect(hWnd, NULL, TRUE);
break;
case ID_FILE_NEW:
MessageBox(hWnd, "File New", "Message", MB_OK);
break;
case ID_FILE_OPEN:
MessageBox(hWnd, "File Open", "Message", MB_OK);
break;
case ID_FILE_SAVE:
MessageBox(hWnd, "File Save", "Message", MB_OK);
break;
case ID_EDIT_COPY:
MessageBox(hWnd, "Edit Copy", "Message", MB_OK);
break;
case ID_EDIT_CUT:
MessageBox(hWnd, "Edit Cut", "Message", MB_OK);
break;
case ID_EDIT_PASTE:
MessageBox(hWnd, "Edit Paste", "Message", MB_OK);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
<b>BOOL AppendMenu( </b>
<i><b> HMENU hMenu, // handle to menu to be changed </b></i>
<i><b> UINT uFlags, // menu-item flags </b></i>
<i><b> UINT uIDNewItem, // menu-item identifier or handle to drop-down menu or </b></i>
submenu
<i><b> LPCTSTR lpNewItem // menu-item content </b></i>
<b>); </b>
UINT CtlType; // type of control
UINT CtlID; // combo box, list box, or button identifier
UINT itemID; // menu item, variable-height list box,
// or combo box identifier
UINT itemWidth; // width of menu item, in pixels
UINT itemHeight; // height of single item in list box menu,
// in pixels
DWORD itemData; // application-defined 32-bit value
} MEASUREITEMSTRUCT;
WM_DRAWITEM
idCtl = (UINT) wParam; // control identifier
lpdis = (LPDRAWITEMSTRUCT) lParam; // item-drawing information
UINT CtlType;
UINT CtlID;
UINT itemID;
UINT itemAction;
UINT itemState;
HWND hwndItem;
HDC hDC;
RECT rcItem;
DWORD itemData;
} DRAWITEMSTRUCT;
// resource.h
// Used by VnMenu.rc
//
#define ID_BRUSH_CROSS 32792
#define ID_BRUSH_HORIZONTAL 32793
#define ID_BRUSH_VERTICAL 32794
#define ID_FIGURE_ELLIPSE 32795
#define ID_FIGURE_RECTANGLE 32796
#define ID_FIGURE_ROUNDRECT 32797
#define ID_FIGURE_CHORD 32798
#define ID_FIGURE_PIE 32799
// VnMenu.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
HFONT MyCreateFont (HDC hdc, char * szFaceName, int nPointSize,
BOOL bBold = FALSE, BOOL bItalic = FALSE)
{
HFONT hFont ;
LOGFONT lf ;
memset(&lf, 0, sizeof(lf));
lf.lfHeight = -MulDiv(nPointSize, GetDeviceCaps(hdc,
LOGPIXELSY), 72);
lf.lfWeight = bBold ? FW_BOLD : FW_NORMAL;
lf.lfItalic = bItalic;
strcpy (lf.lfFaceName, szFaceName) ;
hFont = CreateFontIndirect (&lf) ;
return hFont ;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
struct M_POPUP
{
char *name;
UINT bitmapId;
int nItems;
M_ITEM aItems[MAX_ITEMS];
};
static M_POPUP aVnMenu[] =
{
"&Hoà sô", IDB_FILE, 5,
{
{"Hồ sơ mới", ID_FILE_NEW, MF_OWNERDRAW},
{"Mở hồ sơ", ID_FILE_OPEN, MF_OWNERDRAW},
{"Lưu hồ sơ", ID_FILE_SAVE, MF_OWNERDRAW},
{"", 0, MF_SEPARATOR},
{"In", ID_FILE_PRINT, MF_OWNERDRAW},
{"Thoát", IDM_EXIT, MF_OWNERDRAW},
"&Soạn Thảo", IDB_EDIT, 3,
{
{"Sao chép", ID_EDIT_COPY, MF_OWNERDRAW},
{"Cắt", ID_EDIT_CUT, MF_OWNERDRAW},
{"Daùn", ID_EDIT_PASTE, MF_OWNERDRAW},
},
"Đổi Menu Font", IDB_FONT, 4,
{
{"VNI-Times", ID_FONT_VNI_TIMES, MF_OWNERDRAW},
{"VNI-Courier", ID_FONT_VNI_COURIER, MF_OWNERDRAW},
{"VNI-Aptima", ID_FONT_VNI_APTIMA, MF_OWNERDRAW},
{"VNI-Cooper", ID_FONT_VNI_COOPER, MF_OWNERDRAW}
},
"&Hình", IDB_FIGURE, 5,
{
{"Hình Bầu dục", ID_FIGURE_ELLIPSE, MF_OWNERDRAW},
{"Hình Chữ Nhật", ID_FIGURE_RECTANGLE, MF_OWNERDRAW},
{"Hình chữ nhật trịn", ID_FIGURE_ROUNDRECT, MF_OWNERDRAW},
{"Hình Vành khun", ID_FIGURE_CHORD, MF_OWNERDRAW},
{
{"Thoâng tin", IDM_ABOUT, MF_OWNERDRAW},
}
};
struct FONTMENUDATA
{
UINT id;
TCHAR szFaceName[32];
int nPointSize;
BOOL bBold, bItalics;
};
static FONTMENUDATA aFontData[] =
{
{ID_FONT_VNI_TIMES, "VNI-Times", 12},
{ID_FONT_VNI_COURIER, "VNI-Couri", 12, TRUE},
{ID_FONT_VNI_APTIMA, "VNI-Aptima", 12},
{ID_FONT_VNI_COOPER, "VNI-Cooper", 12, TRUE, TRUE},
};
#define dim(a) (sizeof(a)/sizeof(a[0]))
const int nPopups = dim(aVnMenu);
const int nFonts = dim(aFontData);
HMENU AddMenuPopup(HMENU hMenu, M_POPUP mp)
{
HMENU hMenuPopup = CreatePopupMenu();
AppendMenu (hMenu, MF_POPUP|MF_BITMAP, (UINT)hMenuPopup,
(LPSTR)LoadBitmap (hInst, (LPSTR)mp.bitmapId));
for (int i = 0; i < mp.nItems; i++)
AppendMenu (hMenuPopup, mp.aItems[i].attr, mp.aItems[i].id,
mp.aItems[i].name);
return hMenuPopup;
}
M_ITEM *SearchItem(int n, M_POPUP *a, UINT id)
{
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szName[][MAX_LOADSTRING] = {"Hình Ellipse", "Hình Chữ Nhật", "Hình
Chữ nhật trịn", "Chord", "Pie"};
static HMENU hMenuVn;
static HFONT ahf[nFonts];
static int cxCheck, cyCheck, nBrush;
static WORD nBrushIdx, nFigIdx, nCurFont = 1;
static COLORREF crHighlight, crHighlightText;
static HBRUSH ahbr[7];
M_ITEM *pItem;
switch (message)
{
case WM_CREATE:
int i;
LOGFONT lf;
crHighlight = GetSysColor(COLOR_HIGHLIGHT);
crHighlightText = GetSysColor(COLOR_HIGHLIGHTTEXT);
cxCheck = GetSystemMetrics(SM_CXMENUCHECK);
cyCheck = GetSystemMetrics(SM_CYMENUCHECK);
ZeroMemory(&lf, sizeof(lf));
hdc = GetDC(hWnd);
for (i = 0; i < nFonts; i++)
ahf[i] = MyCreateFont(hdc, aFontData[i].szFaceName,
aFontData[i].nPointSize, aFontData[i].bBold,
aFontData[i].bItalics);
ahbr[0] = CreateSolidBrush(RGB(0,0, 255));
ahbr[1] = CreateHatchBrush(HS_BDIAGONAL, RGB(0,0,255));
ahbr[2] = CreateHatchBrush(HS_FDIAGONAL, RGB(0,0,255));
ahbr[3] = CreateHatchBrush(HS_DIAGCROSS, RGB(0,0,255));
ahbr[4] = CreateHatchBrush(HS_CROSS, RGB(0,0,255));
ahbr[5] = CreateHatchBrush(HS_HORIZONTAL, RGB(0,0,255));
ahbr[6] = CreateHatchBrush(HS_VERTICAL, RGB(0,0,255));
nBrush = 7;
lpmi = (LPMEASUREITEMSTRUCT)lParam;
HFONT hfont, hfontOld;
// switch(lpmi->itemID)
pItem = SearchItem(nPopups, aVnMenu, lpmi->itemID);
if (pItem)
{
hdc = GetDC (hWnd);
for (i = 0; i < dim(aFontData); i++)
break;
if (i < dim(aFontData))
hfont = ahf[i];
else
hfont = ahf[0];
SelectObject (hdc, hfont);
GetTextExtentPoint32(hdc, pItem->name, lstrlen(pItem->name),
&sizeText);
ReleaseDC (hWnd, hdc);
lpmi->itemWidth = sizeText.cx + cxCheck;
lpmi->itemHeight = max(sizeText.cy, cyCheck);
}
break;
case WM_DRAWITEM:
LPDRAWITEMSTRUCT lpdi;
lpdi = (LPDRAWITEMSTRUCT)lParam;
COLORREF crTextOld, crBackOld;
BOOL bSwap;
int xText, yText;
char *szText;
HBRUSH hbrOld;
pItem = SearchItem(nPopups, aVnMenu, lpdi->itemID);
if (pItem)
{
for (i = 0; i < dim(aFontData); i++)
if (lpdi->itemID == aFontData[i].id)
break;
cxCheck = GetSystemMetrics(SM_CXMENUCHECK);
xText = lpdi -> rcItem.left + cxCheck;
yText = lpdi -> rcItem.top;
ExtTextOut(lpdi->hDC, xText, yText, ETO_OPAQUE, &lpdi->rcItem,
szText, strlen(szText), NULL);
if (lpdi->itemID - ID_FONT_VNI_TIMES == nCurFont ||
lpdi->itemID - ID_FIGURE_ELLIPSE == nFigIdx ||
lpdi->itemID - ID_BRUSH_SOLID == nBrushIdx)
{
hbrOld = (HBRUSH)SelectObject(lpdi->hDC, ahbr[0]);
Circle>hDC, lpdi->rcItem.left+cxCheck/2,
(lpdi->rcItem.top + lpdi->rcItem.bottom)/2, 5);
SelectObject(lpdi->hDC, hbrOld);
}
SelectObject (lpdi->hDC, hfontOld);
if (bSwap)
{
SetTextColor(lpdi->hDC, crTextOld);
SetBkColor(lpdi->hDC, crBackOld);
}
}
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case ID_FONT_VNI_TIMES:
case ID_FONT_VNI_COURIER:
case ID_FONT_VNI_APTIMA:
case ID_FONT_VNI_COOPER:
break;
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
GetClientRect(hWnd, &rt);
SelectObject (hdc, ahf[nCurFont]);
DrawText(hdc, szName[nFigIdx], strlen(szName[nFigIdx]), &rt,
DT_CENTER);
SelectObject(hdc, ahbr[nBrushIdx]);
switch(ID_FIGURE_ELLIPSE + nFigIdx)
{
case ID_FIGURE_ELLIPSE:
Ellipse(hdc, rt.right/4, rt.bottom/4, 3*rt.right/4,
3*rt.bottom/4);
break;
case ID_FIGURE_RECTANGLE:
Rectangle(hdc, rt.right/4, rt.bottom/4, 3*rt.right/4,
3*rt.bottom/4);
break;
case ID_FIGURE_ROUNDRECT:
RoundRect(hdc, rt.right/4, rt.bottom/4, 3*rt.right/4,
3*rt.bottom/4, 30, 30);
break;
case ID_FIGURE_PIE:
Pie(hdc, rt.right/4, rt.bottom/4, 3*rt.right/4, 3*rt.bottom/4,
rt.right, rt.bottom/2, 0, 0);
break;
case ID_FIGURE_CHORD:
Chord(hdc, rt.right/4, rt.bottom/4, 3*rt.right/4,
}
Hình 9-8 VnMenu với lựa chọn tiếng Anh
// VnMenu.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
};
static M_POPUP aVnMenu[] =
{
"&Hồ sơ", IDB_FILE, 5,
{
{"Hồ sơ mới", ID_FILE_NEW, MF_OWNERDRAW},
{"Mở hồ sơ", ID_FILE_OPEN, MF_OWNERDRAW},
{"In", ID_FILE_PRINT, MF_OWNERDRAW},
{"Thoát", IDM_EXIT, MF_OWNERDRAW},
},
"&Soạn Thảo", IDB_EDIT, 3,
{
{"Sao cheùp", ID_EDIT_COPY, MF_OWNERDRAW},
{"Cắt", ID_EDIT_CUT, MF_OWNERDRAW},
{"Dán", ID_EDIT_PASTE, MF_OWNERDRAW},
},
"Đổi Menu Font", IDB_FONT, 4,
{
{"VNI-Times", ID_FONT_VNI_TIMES, MF_OWNERDRAW},
{"VNI-Courier", ID_FONT_VNI_COURIER, MF_OWNERDRAW},
{"VNI-Aptima", ID_FONT_VNI_APTIMA, MF_OWNERDRAW},
{"VNI-Cooper", ID_FONT_VNI_COOPER, MF_OWNERDRAW}
},
"&Hình", IDB_FIGURE, 5,
{
{"Hình Chữ Nhật", ID_FIGURE_RECTANGLE, MF_OWNERDRAW},
{"Hình Bầu dục", ID_FIGURE_ELLIPSE, MF_OWNERDRAW},
{"Hình chữ nhật trịn", ID_FIGURE_ROUNDRECT, MF_OWNERDRAW},
{"Hình Vành khun", ID_FIGURE_CHORD, MF_OWNERDRAW},
{"Hình bánh", ID_FIGURE_PIE, MF_OWNERDRAW},
},
"&Chổi vẽ", IDB_BRUSH, 7,
{
{"Thoâng tin", IDM_ABOUT, MF_OWNERDRAW},
}
};
struct FONTMENUDATA
{
UINT id;
TCHAR szFaceName[32];
int nPointSize;
BOOL bBold, bItalics;
};
static FONTMENUDATA aFontData[] =
{
{ID_FONT_VNI_TIMES, "VNI-Times", 12},
{ID_FONT_VNI_COURIER, "VNI-Couri", 12, TRUE},
{ID_FONT_VNI_APTIMA, "VNI-Aptima", 12},
{ID_FONT_VNI_COOPER, "VNI-Cooper", 12, TRUE, TRUE},
};
#define dim(a) (sizeof(a)/sizeof(a[0]))
const int nPopups = dim(aVnMenu);
const int nFonts = dim(aFontData);
HMENU AddMenuPopup(HMENU hMenu, M_POPUP mp)
{
HMENU hMenuPopup = CreatePopupMenu();
AppendMenu (hMenu, MF_POPUP|MF_BITMAP, (UINT)hMenuPopup,
(LPSTR)LoadBitmap (hInst, (LPSTR)mp.bitmapId));
for (int i = 0; i < mp.nItems; i++)
AppendMenu (hMenuPopup, mp.aItems[i].attr, mp.aItems[i].id,
mp.aItems[i].name);
return hMenuPopup;
}
M_ITEM *SearchItem(int n, M_POPUP *a, UINT id)
{
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR* szName[][5] =
{
{"Ellipse", "Rectangle", "RoundRect", "Chord", "Pie"},
{"Hình Bầu dục", "Hình Chữ Nhật", "Hình Chữ nhật trịn", "Hình
vành khun", "Hình chiếc bánh"}
};
static HMENU hMenu, hMenuVn;
static HFONT ahf[nFonts];
static int cxCheck, cyCheck, nBrush;
static WORD nBrushIdx, nFigIdx, nCurFont = 0;
static COLORREF crHighlight, crHighlightText;
static HBRUSH ahbr[7];
static bool bVietNamese = true;
crHighlight = GetSysColor(COLOR_HIGHLIGHT);
crHighlightText = GetSysColor(COLOR_HIGHLIGHTTEXT);
cxCheck = GetSystemMetrics(SM_CXMENUCHECK);
cyCheck = GetSystemMetrics(SM_CYMENUCHECK);
ZeroMemory(&lf, sizeof(lf));
hdc = GetDC(hWnd);
for (i = 0; i < nFonts; i++)
ahf[i] = MyCreateFont(hdc, aFontData[i].szFaceName,
aFontData[i].nPointSize, aFontData[i].bBold,
aFontData[i].bItalics);
ahbr[0] = CreateSolidBrush(RGB(0,0, 255));
hMenuPopup = CreatePopupMenu();
SetMenu(hWnd, hMenuVn);
break;
case WM_MEASUREITEM:
SIZE sizeText;
LPMEASUREITEMSTRUCT lpmi;
lpmi = (LPMEASUREITEMSTRUCT)lParam;
HFONT hfont, hfontOld;
pItem = SearchItem(nPopups, aVnMenu, lpmi->itemID);
if (pItem)
{
hdc = GetDC (hWnd);
for (i = 0; i < dim(aFontData); i++)
if (lpmi->itemID == aFontData[i].id)
break;
if (i < dim(aFontData))
hfont = ahf[i];
else
hfont = ahf[0];
SelectObject (hdc, hfont);
GetTextExtentPoint32(hdc, pItem->name, lstrlen(pItem->name),
&sizeText);
ReleaseDC (hWnd, hdc);
lpmi->itemWidth = sizeText.cx + cxCheck;
lpmi->itemHeight = max(sizeText.cy, cyCheck);
}
break;
case WM_DRAWITEM:
LPDRAWITEMSTRUCT lpdi;
lpdi = (LPDRAWITEMSTRUCT)lParam;
COLORREF crTextOld, crBackOld;
BOOL bSwap;
int xText, yText;
char *szText;
HBRUSH hbrOld;
crBackOld = SetBkColor (lpdi->hDC, crHighlight);
bSwap = TRUE;
}
else
bSwap = FALSE;
cxCheck = GetSystemMetrics(SM_CXMENUCHECK);
ExtTextOut(lpdi->hDC, xText, yText, ETO_OPAQUE, &lpdi->rcItem,
szText, strlen(szText), NULL);
if (lpdi->itemID - ID_FONT_VNI_TIMES == nCurFont ||
lpdi->itemID - ID_FIGURE_ELLIPSE == nFigIdx ||
lpdi->itemID - ID_BRUSH_SOLID == nBrushIdx)
{
hbrOld = (HBRUSH)SelectObject(lpdi->hDC, ahbr[0]);
Circle>hDC, lpdi->rcItem.left+cxCheck/2,
(lpdi->rcItem.top + lpdi->rcItem.bottom)/2, 5);
SelectObject(lpdi->hDC, hbrOld);
}
SelectObject (lpdi->hDC, hfontOld);
if (bSwap)
{
SetTextColor(lpdi->hDC, crTextOld);
SetBkColor(lpdi->hDC, crBackOld);
}
}
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case ID_FONT_VNI_TIMES:
case ID_FONT_VNI_COURIER:
case ID_FONT_VNI_APTIMA:
case ID_FONT_VNI_COOPER:
CheckMenuItem(hMenu, ID_FONT_VNI_TIMES + nCurFont,
MF_UNCHECKED);
CheckMenuItem(hMenu, ID_BRUSH_SOLID + nBrushIdx,
MF_UNCHECKED);
nBrushIdx = wmId - ID_BRUSH_SOLID;
CheckMenuItem(hMenu, wmId, MF_CHECKED);
InvalidateRect(hWnd, NULL, TRUE);
break;
case ID_FIGURE_ELLIPSE:
case ID_FIGURE_RECTANGLE:
case ID_FIGURE_ROUNDRECT:
case ID_FIGURE_CHORD:
CheckMenuItem(hMenu, ID_FIGURE_ELLIPSE + nFigIdx,
MF_UNCHECKED);
nFigIdx = wmId - ID_FIGURE_ELLIPSE;
CheckMenuItem(hMenu, wmId, MF_CHECKED);
InvalidateRect(hWnd, NULL, TRUE);
break;
case ID_OPTION_ENGLISH:
bVietNamese = false;
SetMenu(hWnd, hMenu);
break;
case ID_OPTION_TIENGVIET:
SetMenu(hWnd, hMenuVn);
bVietNamese = true;
break;
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
case ID_FIGURE_RECTANGLE:
Rectangle(hdc, rt.right/4, rt.bottom/4, 3*rt.right/4,
3*rt.bottom/4);
break;
case ID_FIGURE_ROUNDRECT:
RoundRect(hdc, rt.right/4, rt.bottom/4, 3*rt.right/4,
3*rt.bottom/4, 30, 30);
break;
case ID_FIGURE_PIE:
Pie(hdc, rt.right/4, rt.bottom/4, 3*rt.right/4, 3*rt.bottom/4,
rt.right, rt.bottom/2, 0, 0);
break;
case ID_FIGURE_CHORD:
Chord(hdc, rt.right/4, rt.bottom/4, 3*rt.right/4,
3*rt.bottom/4, rt.right, rt.bottom/3, 0, rt.bottom);
break;
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
for (i = 0; i < nBrush; i++)
DeleteObject(ahbr[i]);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// VnMenu.cpp : Defines the entry point for the application.
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
#define MAX_ITEMS 10
struct M_ITEM
{
char *name;
UINT id;
UINT attr;
};
struct M_POPUP
{
char *name;
UINT bitmapId;
int nItems;
M_ITEM aItems[MAX_ITEMS];
};
static M_POPUP aVnMenu[] =
{
"&Hồ sơ", IDB_FILE, 5,
{
{"Hồ sơ mới", ID_FILE_NEW, MF_OWNERDRAW},
{"Mở hồ sơ", ID_FILE_OPEN, MF_OWNERDRAW},
{"Lưu hồ sơ", ID_FILE_SAVE, MF_OWNERDRAW},
{"", 0, MF_SEPARATOR},
{"In", ID_FILE_PRINT, MF_OWNERDRAW},
{"Thoát", IDM_EXIT, MF_OWNERDRAW},
},
"&Soạn Thảo", IDB_EDIT, 3,
{
{"Sao chép", ID_EDIT_COPY, MF_OWNERDRAW},
{"Cắt", ID_EDIT_CUT, MF_OWNERDRAW},
{"Dán", ID_EDIT_PASTE, MF_OWNERDRAW},
},
"Đổi Menu Font", IDB_FONT, 4,
{
},
"&Chổi vẽ", IDB_BRUSH, 7,
{
{"Đặc", ID_BRUSH_SOLID, MF_OWNERDRAW},
{"Chéo ngược", ID_BRUSH_BWDIAGONAL, MF_OWNERDRAW},
{"Chéo xuôi", ID_BRUSH_FWDIAGONAL, MF_OWNERDRAW},
{"Chéo", ID_BRUSH_DIAGCROSS, MF_OWNERDRAW},
{"Ngang doïc", ID_BRUSH_CROSS, MF_OWNERDRAW},
{"Ngang", ID_BRUSH_HORIZONTAL, MF_OWNERDRAW},
{"Doïc", ID_BRUSH_VERTICAL, MF_OWNERDRAW},
"&Tùy Chọn", IDB_OPTION, 1,
{
{"English", ID_OPTION_ENGLISH, MF_OWNERDRAW},
},
"&Hướng dẫn", IDB_HELP, 1,
{
{"Thoâng tin", IDM_ABOUT, MF_OWNERDRAW},
}
};
struct FONTMENUDATA
{
UINT id;
TCHAR szFaceName[32];
int nPointSize;
BOOL bBold, bItalics;
};
static FONTMENUDATA aFontData[] =
{
{ID_FONT_VNI_TIMES, "VNI-Times", 12},
{ID_FONT_VNI_COURIER, "VNI-Couri", 12, TRUE},
{ID_FONT_VNI_APTIMA, "VNI-Aptima", 12},
}
M_ITEM *SearchItem(int n, M_POPUP *a, UINT id)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < a[i].nItems; j++)
if (a[i].aItems[j].id == id)
return &a[i].aItems[j];
}
return NULL;
}
BOOL Circle(HDC hdc, int x, int y, int r)
{
return Ellipse(hdc, x-r, y-r, x+r, y+r);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR* szName[][5] =
{
{"Ellipse", "Rectangle", "RoundRect", "Chord", "Pie"},
{"Hình Bầu dục", "Hình Chữ Nhật", "Hình Chữ nhật trịn", "Hình
vành khuyên", "Hình cánh quạt"}
};
static HMENU hMenu, hMenuVn;
static HFONT ahf[nFonts];
static int cxCheck, cyCheck, nBrush;
static WORD nBrushIdx, nFigIdx, nCurFont = 0;
static COLORREF crHighlight, crHighlightText;
static HBRUSH ahbr[7];
static bool bVietNamese = true;
M_ITEM *pItem;
ahf[i] = MyCreateFont(hdc, aFontData[i].szFaceName,
aFontData[i].bItalics);
ahbr[0] = CreateSolidBrush(RGB(0,0, 255));
ahbr[1] = CreateHatchBrush(HS_BDIAGONAL, RGB(0,0,255));
ahbr[2] = CreateHatchBrush(HS_FDIAGONAL, RGB(0,0,255));
ahbr[3] = CreateHatchBrush(HS_DIAGCROSS, RGB(0,0,255));
ahbr[4] = CreateHatchBrush(HS_CROSS, RGB(0,0,255));
ahbr[5] = CreateHatchBrush(HS_HORIZONTAL, RGB(0,0,255));
ahbr[6] = CreateHatchBrush(HS_VERTICAL, RGB(0,0,255));
nBrush = 7;
ReleaseDC(hWnd, hdc);
hMenu = GetMenu(hWnd);
hMenuVn = CreateMenu();
for (i = 0; i < nPopups; i++)
AddMenuPopup(hMenuVn, aVnMenu[i]);
HMENU hMenuPopup;
hMenuPopup = CreatePopupMenu();
SetMenu(hWnd, hMenuVn);
break;
case WM_MEASUREITEM:
SIZE sizeText;
LPMEASUREITEMSTRUCT lpmi;
lpmi = (LPMEASUREITEMSTRUCT)lParam;
HFONT hfont, hfontOld;
switch(lpmi->itemID)
{
case ID_FIGURE_ELLIPSE:
case ID_FIGURE_RECTANGLE:
case ID_FIGURE_ROUNDRECT:
case ID_FIGURE_CHORD:
case ID_FIGURE_PIE:
lpmi->itemWidth = 80;
lpmi->itemHeight = 30;
break;
for (i = 0; i < dim(aFontData); i++)
if (lpmi->itemID == aFontData[i].id)
break;
if (i < dim(aFontData))
hfont = ahf[i];
else
hfont = ahf[nCurFont];
SelectObject (hdc, hfont);
GetTextExtentPoint32(hdc, pItem->name, lstrlen(pItem->name),
&sizeText);
ReleaseDC (hWnd, hdc);
lpmi->itemWidth = sizeText.cx + cxCheck;
lpmi->itemHeight = max(sizeText.cy, cyCheck);
}
break;
}
break;
case WM_DRAWITEM:
LPDRAWITEMSTRUCT lpdi;
lpdi = (LPDRAWITEMSTRUCT)lParam;
COLORREF crTextOld, crBackOld;
BOOL bSwap;
int xText, yText;
char *szText;
switch(lpdi->itemID)
{
case ID_FIGURE_ELLIPSE:
case ID_FIGURE_RECTANGLE:
case ID_FIGURE_ROUNDRECT:
case ID_FIGURE_CHORD:
case ID_FIGURE_PIE:
HBRUSH hbrOld;
int orgRop;
hbrOld = (HBRUSH)SelectObject(lpdi->hDC, ahbr[nBrushIdx]);
if (lpdi->itemState & ODS_SELECTED)
{
xText = lpdi -> rcItem.left;
yText = lpdi -> rcItem.top;
lpdi->rcItem.right, lpdi->rcItem.bottom-2);
break;
case ID_FIGURE_RECTANGLE:
Rectangle(>hDC, >rcItem.left+cxCheck,
lpdi->rcItem.top + 2,
lpdi->rcItem.right, lpdi->rcItem.bottom-2);
break;
case ID_FIGURE_ROUNDRECT:
RoundRect(>hDC, >rcItem.left+cxCheck,
lpdi->rcItem.top + 2,
lpdi->rcItem.right, lpdi->rcItem.bottom-2, 5, 5);
break;
case ID_FIGURE_CHORD:
Chord(>hDC, >rcItem.left+cxCheck,
lpdi->rcItem.top + 2, lpdi->rcItem.right, lpdi->rcItem.bottom-2,
>rcItem.right, >rcItem.bottom-10,
lpdi->rcItem.left, (lpdi->rcItem.top+lpdi->rcItem.bottom)/2);
break;
case ID_FIGURE_PIE:
Pie(lpdi->hDC, lpdi->rcItem.left+cxCheck, lpdi->rcItem.top
+ 2, lpdi->rcItem.right, lpdi->rcItem.bottom+20,
lpdi->rcItem.right,
(lpdi->rcItem.top+lpdi->rcItem.bottom)/2,
lpdi->rcItem.left, lpdi->rcItem.top);
break;
}
if (lpdi->itemID - ID_FIGURE_ELLIPSE == nFigIdx)
{
SelectObject(lpdi->hDC, ahbr[0]);
Circle>hDC, lpdi->rcItem.left+cxCheck/2,
(lpdi->rcItem.top + lpdi->rcItem.bottom)/2, 5);
}
if (bSwap)
{
SetBkColor(lpdi->hDC, crBackOld);
SetROP2(lpdi->hDC, orgRop);
}
xText = lpdi -> rcItem.left;
yText = lpdi -> rcItem.top;
crBackOld = SetBkColor (lpdi->hDC, crHighlight);
orgRop = SetROP2(lpdi->hDC, R2_XORPEN);
bSwap = true;
}
cxCheck = GetSystemMetrics(SM_CXMENUCHECK);
ExtTextOut(lpdi->hDC, xText, yText, ETO_OPAQUE, &lpdi->rcItem,
"", 0, NULL);
Rectangle(lpdi->hDC, lpdi->rcItem.left+cxCheck, lpdi->rcItem.top
+ 2,
lpdi->rcItem.right, lpdi->rcItem.bottom-2);
if (lpdi->itemID - ID_BRUSH_SOLID == nBrushIdx)
{
SelectObject(lpdi->hDC, ahbr[0]);
Circle>hDC, lpdi->rcItem.left+cxCheck/2,
(lpdi->rcItem.top + lpdi->rcItem.bottom)/2, 5);
}
if (bSwap)
{
SetBkColor(lpdi->hDC, crBackOld);
SetROP2(lpdi->hDC, orgRop);
}
SelectObject(lpdi->hDC, hbrOld);
break;
default:
pItem = SearchItem(nPopups, aVnMenu, lpdi->itemID);
if (pItem)
{
for (i = 0; i < dim(aFontData); i++)
if (lpdi->itemID == aFontData[i].id)
break;
if (i < dim(aFontData))
hfont = ahf[i];
else
hfont = ahf[nCurFont];
szText = pItem->name;
ExtTextOut(lpdi->hDC, xText, yText, ETO_OPAQUE, &lpdi->rcItem,
szText, strlen(szText), NULL);
if (lpdi->itemID - ID_FONT_VNI_TIMES == nCurFont ||
lpdi->itemID - ID_FIGURE_ELLIPSE == nFigIdx ||
lpdi->itemID - ID_BRUSH_SOLID == nBrushIdx)
{
hbrOld = (HBRUSH)SelectObject(lpdi->hDC, ahbr[0]);
Circle>hDC, lpdi->rcItem.left+cxCheck/2,
(lpdi->rcItem.top + lpdi->rcItem.bottom)/2, 5);
SelectObject(lpdi->hDC, hbrOld);
}
SelectObject (lpdi->hDC, hfontOld);
if (bSwap)
{
SetTextColor(lpdi->hDC, crTextOld);
}
break;
}
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case ID_FONT_VNI_TIMES:
case ID_FONT_VNI_COURIER:
case ID_FONT_VNI_APTIMA:
case ID_FONT_VNI_COOPER:
CheckMenuItem(hMenu, ID_FONT_VNI_TIMES + nCurFont,
MF_UNCHECKED);
nCurFont = wmId - ID_FONT_VNI_TIMES;
CheckMenuItem(hMenu, wmId, MF_CHECKED);
InvalidateRect(hWnd, NULL, TRUE);
break;
case ID_FIGURE_ROUNDRECT:
case ID_FIGURE_CHORD:
case ID_FIGURE_PIE:
CheckMenuItem(hMenu, ID_FIGURE_ELLIPSE + nFigIdx,
MF_UNCHECKED);
nFigIdx = wmId - ID_FIGURE_ELLIPSE;
CheckMenuItem(hMenu, wmId, MF_CHECKED);
InvalidateRect(hWnd, NULL, TRUE);
break;
case ID_OPTION_ENGLISH:
bVietNamese = false;
SetMenu(hWnd, hMenu);
break;
case ID_OPTION_TIENGVIET:
SetMenu(hWnd, hMenuVn);
bVietNamese = true;
break;
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
GetClientRect(hWnd, &rt);
SelectObject (hdc, ahf[nCurFont]);
DrawText(hdc, szName[bVietNamese][nFigIdx],
strlen(szName[bVietNamese][nFigIdx]), &rt, DT_CENTER);
SelectObject(hdc, ahbr[nBrushIdx]);
switch(ID_FIGURE_ELLIPSE + nFigIdx)
{
Pie(hdc, rt.right/4, rt.bottom/4, 3*rt.right/4, 3*rt.bottom/4,
rt.right, rt.bottom/2, 0, 0);
break;
case ID_FIGURE_CHORD:
Chord(hdc, rt.right/4, rt.bottom/4, 3*rt.right/4,
3*rt.bottom/4, rt.right, rt.bottom/3, 0, rt.bottom);
break;
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
for (i = 0; i < nBrush; i++)
DeleteObject(ahbr[i]);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Hình 9-13 Các menu item làbitmap
// VnMenu.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
//...
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
#define MAX_ITEMS 10
struct M_ITEM
{
{
"&Hồ sơ", IDB_FILE, 6,
{
{"Hồ sơ mới", ID_FILE_NEW, MF_BITMAP, IDB_FILE_NEW},
{"Mở hồ sơ", ID_FILE_OPEN, MF_BITMAP, IDB_FILE_OPEN},
{"Lưu hồ sơ", ID_FILE_SAVE, MF_BITMAP, IDB_FILE_SAVE},
{"", 0, MF_SEPARATOR},
{"In", ID_FILE_PRINT, MF_BITMAP, IDB_FILE_PRINT},
{"Thoát", IDM_EXIT, MF_BITMAP, IDB_FILE_EXIT},
},
"&Soạn Thảo", IDB_EDIT, 3,
{
{"Sao cheùp", ID_EDIT_COPY, MF_BITMAP, IDB_EDIT_COPY},
{"Cắt", ID_EDIT_CUT, MF_BITMAP, IDB_EDIT_CUT},
{"Dán", ID_EDIT_PASTE, MF_BITMAP, IDB_EDIT_PASTE},
},
"Đổi Menu Font", IDB_FONT, 4,
{
{"VNI-Times", ID_FONT_VNI_TIMES, MF_BITMAP, IDB_FONT_TIMES},
{"VNI-Courier", ID_FONT_VNI_COURIER, MF_BITMAP, IDB_FONT_COURIER},
"&Hình", IDB_FIGURE, 5,
{
{"Hình Chữ Nhật", ID_FIGURE_ELLIPSE, MF_BITMAP,
IDB_FIGURE_ELLIPSE},
{"Hình Bầu dục", ID_FIGURE_RECTANGLE, MF_BITMAP,
IDB_FIGURE_RECTANGLE},
{"Hình chữ nhật trịn", ID_FIGURE_ROUNDRECT, MF_BITMAP,
IDB_FIGURE_ROUNDRECT},
{"Hình Vành khuyên", ID_FIGURE_CHORD, MF_BITMAP, IDB_FIGURE_CHORD},
{"Hình bánh", ID_FIGURE_PIE, MF_BITMAP, IDB_FIGURE_PIE},
},
"&Chổi vẽ", IDB_BRUSH, 8,
{
{"Đặc", ID_BRUSH_SOLID, MF_BITMAP, IDB_BRUSH_SOLID},
{"...", ID_BRUSH_SOLID, MF_SEPARATOR},
{
{"Thoâng tin", IDM_ABOUT, MF_BITMAP, IDB_HELP_THONGTIN},
};
struct FONTMENUDATA
{
UINT id;
TCHAR szFaceName[32];
int nPointSize;
BOOL bBold, bItalics;
};
static FONTMENUDATA aFontData[] =
{
{ID_FONT_VNI_TIMES, "VNI-Times", 12},
{ID_FONT_VNI_COURIER, "VNI-Couri", 12, TRUE},
{ID_FONT_VNI_APTIMA, "VNI-Aptima", 12},
{ID_FONT_VNI_COOPER, "VNI-Cooper", 12, TRUE, TRUE},
};
#define dim(a) (sizeof(a)/sizeof(a[0]))
const int nPopups = dim(aVnMenu);
const int nFonts = dim(aFontData);
HMENU AddMenuPopup(HMENU hMenu, M_POPUP mp)
{
HMENU hMenuPopup = CreatePopupMenu();
AppendMenu (hMenu, MF_POPUP|MF_BITMAP, (UINT)hMenuPopup,
(LPSTR)LoadBitmap (hInst, (LPSTR)mp.bitmapId));
for (int i = 0; i < mp.nItems; i++)
if (mp.aItems[i].attr & MF_BITMAP)
AppendMenu (hMenuPopup, mp.aItems[i].attr, mp.aItems[i].id,
(LPSTR)LoadBitmap(hInst, (LPSTR)mp.aItems[i].bitmapId));
else
AppendMenu (hMenuPopup, mp.aItems[i].attr, mp.aItems[i].id,
mp.aItems[i].name);
BOOL Circle(HDC hdc, int x, int y, int r)
{
return Ellipse(hdc, x-r, y-r, x+r, y+r);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR* szName[][5] =
{
{"Ellipse", "Rectangle", "RoundRect", "Chord", "Pie"},
{"Hình Bầu dục", "Hình Chữ Nhật", "Hình Chữ nhật trịn", "Hình
vành khun", "Hình chiếc bánh"}
};
static HMENU hMenu, hMenuVn;
static HFONT ahf[nFonts];
static int cxCheck, cyCheck, nBrush;
static WORD nBrushIdx, nFigIdx, nCurFont = 0;
static COLORREF crHighlight, crHighlightText;
static HBRUSH ahbr[7];
static bool bVietNamese = true;
switch (message)
{
case WM_CREATE:
LOGFONT lf;
crHighlight = GetSysColor(COLOR_HIGHLIGHT);
crHighlightText = GetSysColor(COLOR_HIGHLIGHTTEXT);
cxCheck = GetSystemMetrics(SM_CXMENUCHECK);
cyCheck = GetSystemMetrics(SM_CYMENUCHECK);
ZeroMemory(&lf, sizeof(lf));
hdc = GetDC(hWnd);
for (i = 0; i < nFonts; i++)
ahf[i] = MyCreateFont(hdc, aFontData[i].szFaceName,
aFontData[i].nPointSize, aFontData[i].bBold,
aFontData[i].bItalics);
for (i = 0; i < nPopups; i++)
AddMenuPopup(hMenuVn, aVnMenu[i]);
HMENU hMenuPopup;
hMenuPopup = CreatePopupMenu();
SetMenu(hWnd, hMenuVn);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case ID_FONT_VNI_TIMES:
case ID_FONT_VNI_COURIER:
case ID_FONT_VNI_APTIMA:
case ID_FONT_VNI_COOPER:
CheckMenuItem(hMenu, ID_FONT_VNI_TIMES + nCurFont,
MF_UNCHECKED);
nCurFont = wmId - ID_FONT_VNI_TIMES;
CheckMenuItem(hMenu, wmId, MF_CHECKED);
InvalidateRect(hWnd, NULL, TRUE);
break;
case ID_BRUSH_SOLID:
case ID_BRUSH_BWDIAGONAL:
case ID_BRUSH_FWDIAGONAL:
case ID_BRUSH_DIAGCROSS:
case ID_BRUSH_CROSS:
case ID_BRUSH_HORIZONTAL:
case ID_BRUSH_VERTICAL:
CheckMenuItem(hMenu, ID_BRUSH_SOLID + nBrushIdx,
MF_UNCHECKED);
nBrushIdx = wmId - ID_BRUSH_SOLID;
CheckMenuItem(hMenu, wmId, MF_CHECKED);
InvalidateRect(hWnd, NULL, TRUE);
break;
case ID_OPTION_TIENGVIET:
SetMenu(hWnd, hMenuVn);
bVietNamese = true;
break;
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
GetClientRect(hWnd, &rt);
SelectObject (hdc, ahf[nCurFont]);
DrawText(hdc, szName[bVietNamese][nFigIdx],
strlen(szName[bVietNamese][nFigIdx]), &rt, DT_CENTER);
SelectObject(hdc, ahbr[nBrushIdx]);
switch(ID_FIGURE_ELLIPSE + nFigIdx)
{
case ID_FIGURE_ELLIPSE:
Ellipse(hdc, rt.right/4, rt.bottom/4, 3*rt.right/4,
3*rt.bottom/4);
break;
case ID_FIGURE_RECTANGLE:
Rectangle(hdc, rt.right/4, rt.bottom/4, 3*rt.right/4,
3*rt.bottom/4);
break;
case ID_FIGURE_ROUNDRECT:
RoundRect(hdc, rt.right/4, rt.bottom/4, 3*rt.right/4,
3*rt.bottom/4, 30, 30);
break;
case ID_FIGURE_PIE:
Pie(hdc, rt.right/4, rt.bottom/4, 3*rt.right/4, 3*rt.bottom/4,
rt.right, rt.bottom/2, 0, 0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
typedef struct _WNDCLASS {
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HANDLE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
} WNDCLASS;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
// ...
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// …
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
<i><b> DWORD dwExStyle, // extended window style </b></i>
<i><b> LPCTSTR lpClassName, // pointer to registered class name </b></i>
<i><b> LPCTSTR lpWindowName, // pointer to window name </b></i>
<i><b> DWORD dwStyle, // window style </b></i>
<i><b> int x, // horizontal position of window </b></i>
<i><b> int y, // vertical position of window </b></i>
<i><b> int nWidth, // window width </b></i>
<i><b> int nHeight, // window height </b></i>
<i><b> HWND hWndParent, // handle to parent or owner window </b></i>
<i><b> HMENU hMenu, // handle to menu, or child-window identifier </b></i>
<i><b> HINSTANCE hInstance, // handle to application instance </b></i>
<i><b> int nIndex // system metric or configuration setting to retrieve </b></i>
<b>);</b>
Hình 10-1 Cửa sổ con
// Mdi.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];// The title bar text
TCHAR szTextWndClass[MAX_LOADSTRING];// The title bar text
TCHAR szBallWndClass[MAX_LOADSTRING];// The title bar text
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
ATOM TextWndRegisterClass(HINSTANCE hInstance);
ATOM BallWndRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK TextWndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK BallWndProc(HWND, UINT, WPARAM, LPARAM);
BallWndRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
return FALSE;
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_MDI);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
// FUNCTION: MyRegisterClass()
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
ATOM TextWndRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
LoadString(hInstance, IDS_TEXTCLASS, szTextWndClass, MAX_LOADSTRING);
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)TextWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.lpszClassName = szTextWndClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szBallWndClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
// FUNCTION: InitInstance(HANDLE, int)
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
PAINTSTRUCT ps;
HDC hdc;
TCHAR szParent[MAX_LOADSTRING];
HWND hWndChild;
LoadString(hInst, IDS_PARENT, szParent, MAX_LOADSTRING);
static int xx, yy;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case ID_FILE_NEWTEXT:
hWndChild = CreateWindow(szTextWndClass, szTitle,
WS_OVERLAPPEDWINDOW | WS_CHILD | WS_CLIPSIBLINGS,
xx, yy, 300, 150, hWnd, NULL, hInst, NULL);
if (!hWndChild)
return TRUE;
xx += 20; yy += 20;
if (xx > 70) xx = yy = 0;
ShowWindow(hWndChild, SW_SHOW);
UpdateWindow(hWndChild);
break;
case ID_FILE_NEWBALL:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd,
(DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, szParent, strlen(szParent), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK TextWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK BallWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
PAINTSTRUCT ps;
HDC hdc;
static int xPos, yPos, dx = 5, dy = 5;
static int r = 20;
RECT rt;
switch (message)
{
case WM_CREATE:
SetTimer(hWnd, 0, 8, NULL);
GetClientRect(hWnd, &rt);
xPos = rt.right/2;