需求:在窗口中按'b',以黑色绘制曲线,按'r'以红色绘制曲线。默认则以黑色绘制。wm_char中进行选择selectobject, 这个函数有hdc,可是每次执行到wm_paint的时候,wm_paint里获得的dc的值不一样,导致无法绘制。
// test3.cpp : 定义应用程序的入口点。
//#include "stdafx.h"
#include "test3.h"#define MAX_LOADSTRING 100#define TWOPI 2*3.1415#define NUM 100// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable; // 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_TEST3, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance); // 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
} hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TEST3)); // 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} return (int) msg.wParam;}LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
static HDC hdc; static HPEN hRedPen; POINT pt[NUM]; RECT rect;
int x,y;
static int cxClient, cyClient; switch (message)
{ case WM_CREATE: hRedPen=CreatePen(PS_SOLID,3,RGB(255,90,33));
break;
case WM_SIZE:
cxClient=LOWORD(lParam);
cyClient=HIWORD(lParam);
break; case WM_CHAR: if(LOWORD(wParam)==_T('r')) //red
{
SelectObject(hdc,hRedPen);
}
if(LOWORD(wParam)==_T('b'))
{
SelectObject(hdc,GetStockObject(BLACK_BRUSH));
}
GetClientRect(hWnd,&rect);
InvalidateRect(hWnd,&rect,FALSE); break; case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint (hWnd, &ps) ;
Rectangle (hdc, cxClient / 8, cyClient / 8, 7 * cxClient / 8, 7 * cyClient / 8) ;
Ellipse(hdc,cxClient / 8, cyClient / 8,7 * cxClient / 8, 7 * cyClient / 8) ;
MoveToEx(hdc,0,0,NULL); LineTo(hdc,cxClient,cyClient); MoveToEx(hdc,cxClient,0,NULL); LineTo(hdc,0,cyClient); RoundRect(hdc,cxClient/4,cyClient/4,cxClient*3/4,cyClient*3/4,cxClient/4,cyClient/4); EndPaint (hWnd, &ps) ; return 0 ; break;
case WM_DESTROY: DeleteObject(hRedPen); PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// test3.cpp : 定义应用程序的入口点。
//#include "stdafx.h"
#include "test3.h"#define MAX_LOADSTRING 100#define TWOPI 2*3.1415#define NUM 100// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable; // 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_TEST3, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance); // 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
} hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TEST3)); // 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} return (int) msg.wParam;}LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
static HDC hdc; static HPEN hRedPen; POINT pt[NUM]; RECT rect;
int x,y;
static int cxClient, cyClient; switch (message)
{ case WM_CREATE: hRedPen=CreatePen(PS_SOLID,3,RGB(255,90,33));
break;
case WM_SIZE:
cxClient=LOWORD(lParam);
cyClient=HIWORD(lParam);
break; case WM_CHAR: if(LOWORD(wParam)==_T('r')) //red
{
SelectObject(hdc,hRedPen);
}
if(LOWORD(wParam)==_T('b'))
{
SelectObject(hdc,GetStockObject(BLACK_BRUSH));
}
GetClientRect(hWnd,&rect);
InvalidateRect(hWnd,&rect,FALSE); break; case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint (hWnd, &ps) ;
Rectangle (hdc, cxClient / 8, cyClient / 8, 7 * cxClient / 8, 7 * cyClient / 8) ;
Ellipse(hdc,cxClient / 8, cyClient / 8,7 * cxClient / 8, 7 * cyClient / 8) ;
MoveToEx(hdc,0,0,NULL); LineTo(hdc,cxClient,cyClient); MoveToEx(hdc,cxClient,0,NULL); LineTo(hdc,0,cyClient); RoundRect(hdc,cxClient/4,cyClient/4,cxClient*3/4,cyClient*3/4,cxClient/4,cyClient/4); EndPaint (hWnd, &ps) ; return 0 ; break;
case WM_DESTROY: DeleteObject(hRedPen); PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
enum PENTYPE{black,red};
int gSelected=black;现在的问题导致矩形,椭圆等形状全部变黑色,而且按'r'不管用,UpdateWindow根本不会触发wm_paint!!!
只好换成InvalidRect,什么原因???
// UpdateWindow(hWnd); GetClientRect(hWnd,&rect); InvalidateRect(hWnd,&rect,TRUE);LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
static HDC hdc; static HPEN hRedPen; POINT pt[NUM]; RECT rect;
int x,y;
static int cxClient, cyClient; switch (message)
{ case WM_CREATE: hRedPen=CreatePen(PS_SOLID,3,RGB(255,90,33));
break;
case WM_SIZE:
cxClient=LOWORD(lParam);
cyClient=HIWORD(lParam);
break; case WM_CHAR:
if(LOWORD(wParam)==_T('r')) //red
gSelected=red;
else if(LOWORD(wParam)==_T('b')) //black
gSelected=black; UpdateWindow(hWnd);
break; case WM_COMMAND:
..............................................................
break;
case WM_PAINT:
hdc = BeginPaint (hWnd, &ps) ; switch(gSelected)
{
case black:
SelectObject(hdc,GetStockObject(BLACK_BRUSH));
break;
case red:
SelectObject(hdc,hRedPen);
default:
break;
}
Rectangle (hdc, cxClient / 8, cyClient / 8, 7 * cxClient / 8, 7 * cyClient / 8) ; Ellipse(hdc,cxClient / 8, cyClient / 8,7 * cxClient / 8, 7 * cyClient / 8) ;
MoveToEx(hdc,0,0,NULL); LineTo(hdc,cxClient,cyClient); MoveToEx(hdc,cxClient,0,NULL); LineTo(hdc,0,cyClient); RoundRect(hdc,cxClient/4,cyClient/4,cxClient*3/4,cyClient*3/4,cxClient/4,cyClient/4); EndPaint (hWnd, &ps) ; return 0 ;
break;
case WM_DESTROY: DeleteObject(hRedPen); PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
1.换成InvalidateRect后,就可以绘制红色的了,UpdateWindow为什么不行?2.黑色曲线绘制没达到预想的效果,把所有的矩形区域,全部涂成黑色的了。而用红色曲线绘制图形的时候,则是白色填充,红色曲线绘图.2个问题.我应该阐述清楚
SelectObject(hdc,GetStockObject(BLACK_BRUSH));
break;
case red:
SelectObject(hdc,hRedPen);1. 一个是 Pen, 一个是 Brush ?
2.HBRUSH old =(HBRUSH)SelectObject(hdc,GetStockObject(BLACK_BRUSH));
用后要恢复:
SelectObject(hdc,old);
UpdateWindow是快速的产生一个wm_paint,迫使case wm_paint被调用按照这个, 那么 case WM_CHAR:
if(LOWORD(wParam)==_T('r')) //red
gSelected=red;
else if(LOWORD(wParam)==_T('b')) //black
gSelected=black;
UpdateWindow(hWnd);
break;case wm_paint会被调用的。结果事宜愿为
为什么要old?去掉brush导致的错误就2个笔,一个红色,一个黑色。wm_destroy里删除红色的,就可以啊黑色的,是系统管理的吧,想不通,为什么要恢复?
一般是不会无效的,或许这个原因导致,UpdateWindow不管用
已经删了啊亲 case WM_DESTROY:
DeleteObject(hRedPen);
PostQuitMessage(0);
break;
pen 删除掉 :
DeleteObject(hRedPen);
SelectObject(hOld);
DeleteObject(hRedPen);