一个SDK来实现普通画图跟双缓冲画图区别的小程序,能运行但有问题。

yiruirui0507 2011-01-19 03:59:03
#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
void PThanshu(HWND);//普通画图函数
void DHChanshu(HWND);//双缓冲画图函数

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName [] = TEXT ("GDI") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;

wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = szAppName;
wndclass.lpszClassName = szAppName ;

if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}

hwnd = CreateWindow (szAppName, TEXT ("GDI TEST"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;

ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;

while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
static int cxClient, cyClient;
static int radius=1;
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{

HDC hdc;
HINSTANCE hInstance ;
static int pt,gdi;//PT--普通画图,GDI--双缓冲画图
PAINTSTRUCT ps ;
RECT rect;

TCHAR szAppName[]="GDI";

switch (message)
{
case WM_CREATE:
SetTimer(hwnd,1,1000,NULL);
hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;

return 0 ;
case WM_TIMER:
//GetClientRect(hwnd,&rect);//本打算在这里触发WM_PAINT消息的
// InvalidateRect(hwnd,&rect,TRUE);
if(radius<16)
{radius++;}
else
{radius=0;}

if(pt)
{
PThanshu(hwnd);//普通画图
}
else if(gdi)
{
DHChanshu(hwnd);//双缓冲画图
}
else
return 0;


case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
return 0 ;

case WM_PAINT:
/*if(pt==1)
{
hdc = BeginPaint (hwnd, &ps) ;
for(int x=0;x<cxClient;x+=16)
for(int y=0;y<cyClient;y=+16)
{
Ellipse(hdc,x,y,x+radius,y+radius);

}
EndPaint (hwnd, &ps) ;
}
else
{
hdc=BeginPaint (hwnd, &ps) ;
DrawText(hdc,szAppName,-1,&rect,DT_CENTER);
EndPaint(hwnd,&ps);

}*/
hdc=BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rect);
DrawText(hdc,szAppName,-1,&rect,DT_CENTER);
EndPaint(hwnd,&ps);

return 0 ;
case WM_COMMAND:
if(lParam==0)
{
switch(wParam)
{

case IDM_PT://普通画图菜单项ID
pt=1;
gdi=0;
return 0;
case IDM_DHC://双缓冲画图菜单项ID
gdi=1;
pt=0;
return 0;
default:
return 0;

}
}


case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
void PThanshu(HWND hwnd)
{
HDC hdc=GetDC(hwnd);
RECT rect;
GetClientRect(hwnd,&rect);

for(int x=0;x<cxClient;x+=16)
for(int y=0;y<cyClient;y=+16)
{
Ellipse(hdc,x,y,x+radius,y+radius);

}
ReleaseDC(hwnd,hdc);
}
void DHChanshu(HWND hwnd)//暂且没实现
{
MessageBox(hwnd,TEXT("zhaoxujing"),TEXT("yiruirui"),MB_OK);
}


以上是代码,能够运行,但是运行过程中我单击 普通画图的时候仅仅画了2个椭圆,然后就没了,关闭出现无响应的情况,可以结束进程给予关闭。这里什么导致的这个问题呢,麻烦大家给看看。3Q!!!
...全文
265 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
yiruirui0507 2011-01-19
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 varding 的回复:]
引用 12 楼 yiruirui0507 的回复:

C/C++ code
void DHChanshu(HWND hwnd)//暂且没实现
{
//MessageBox(hwnd,TEXT("zhaoxujing"),TEXT("yiruirui"),MB_OK);
HDC hdc=GetDC(hwnd);
RECT rect;
GetClientRect(hwnd,&a……
[/Quote]

不是这里的问题,FILLRECT(HDCMEM,&RECT,NULL)就OK了,是填充内存设备内容。谢谢。
varding 2011-01-19
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 yiruirui0507 的回复:]

C/C++ code
void DHChanshu(HWND hwnd)//暂且没实现
{
//MessageBox(hwnd,TEXT("zhaoxujing"),TEXT("yiruirui"),MB_OK);
HDC hdc=GetDC(hwnd);
RECT rect;
GetClientRect(hwnd,&rect);
cxClien……
[/Quote]
FillRect(hdc,&rect,NULL);
你的画刷是NULL,画出来就是黑的

yiruirui0507 2011-01-19
  • 打赏
  • 举报
回复
void DHChanshu(HWND hwnd)//暂且没实现
{
//MessageBox(hwnd,TEXT("zhaoxujing"),TEXT("yiruirui"),MB_OK);
HDC hdc=GetDC(hwnd);
RECT rect;
GetClientRect(hwnd,&rect);
cxClient=rect.right;
cyClient=rect.bottom;

HDC hdcmem=CreateCompatibleDC(hdc);
HBITMAP hbitmap=CreateCompatibleBitmap(hdc,cxClient,cyClient);
SelectObject(hdcmem,hbitmap);
FillRect(hdc,&rect,NULL);
for(int x=0;x<cxClient;x+=16)
for(int y=0;y<cyClient;y+=16)
{
Ellipse(hdcmem,x,y,x+radius,y+radius);

}
BitBlt(hdc,0,0,cxClient,cyClient,hdcmem,0,0,SRCCOPY);
ReleaseDC(hwnd,hdc);

}

这个函数是实现的双缓冲绘图,不晓得为什么每次都有黑色背景?很奇怪。。。
yiruirui0507 2011-01-19
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 varding 的回复:]
引用 5 楼 yiruirui0507 的回复:

引用 3 楼 happyparrot 的回复:
for(int y=0;y<cyClient;y=+16)
应该是for(int y=0;y<cyClient;y+=16)


哦,多谢提醒啊,这里改了之后整个客户区倒是有椭圆了,但是椭圆没变大???没按想象中的那样,椭圆从小变成大。



画图前先用FillSolidRect清除背……
[/Quote]
FillSolidRect是MFC里面的,SDK中没啊???
yiruirui0507 2011-01-19
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 varding 的回复:]
我把你的代码测试了下,你的WM_SIZE里面得到的大小有问题



C/C++ code
case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;


改成这个:

C/C++ code
void PThanshu(HWND hwnd)
{……
[/Quote]
哦,多谢,你的这个的确可以,我的cxClient,cyClient都是全局变量啊,所以我认为放置在WM_SIZE中会比较准确点。没想到,这里竟然也能出问题????
varding 2011-01-19
  • 打赏
  • 举报
回复
我把你的代码测试了下,你的WM_SIZE里面得到的大小有问题

 case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;


改成这个:
void PThanshu(HWND hwnd)
{
HDC hdc=GetDC(hwnd);
RECT rect;

GetClientRect(hwnd,&rect);

cxClient = rect.right;//添加这2个就行了
cyClient = rect.bottom;
...
}

快乐鹦鹉 2011-01-19
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 yiruirui0507 的回复:]
引用 3 楼 happyparrot 的回复:
for(int y=0;y<cyClient;y=+16)
应该是for(int y=0;y<cyClient;y+=16)


哦,多谢提醒啊,这里改了之后整个客户区倒是有椭圆了,但是椭圆没变大???没按想象中的那样,椭圆从小变成大。
[/Quote]
椭圆直径一直是1???
varding 2011-01-19
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 yiruirui0507 的回复:]

引用 3 楼 happyparrot 的回复:
for(int y=0;y<cyClient;y=+16)
应该是for(int y=0;y<cyClient;y+=16)


哦,多谢提醒啊,这里改了之后整个客户区倒是有椭圆了,但是椭圆没变大???没按想象中的那样,椭圆从小变成大。
[/Quote]
画图前先用FillSolidRect清除背景试试
varding 2011-01-19
  • 打赏
  • 举报
回复
你这直接绘图的最好放到WM_PAINT里面,timer里InvalidRect就行了
yiruirui0507 2011-01-19
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 happyparrot 的回复:]
for(int y=0;y<cyClient;y=+16)
应该是for(int y=0;y<cyClient;y+=16)
[/Quote]

哦,多谢提醒啊,这里改了之后整个客户区倒是有椭圆了,但是椭圆没变大???没按想象中的那样,椭圆从小变成大。
快乐鹦鹉 2011-01-19
  • 打赏
  • 举报
回复
由于你写成了y=+16,所以y的值一直不变化,导致死循环,而y只出现两个值,即y=0和y=16
快乐鹦鹉 2011-01-19
  • 打赏
  • 举报
回复
for(int y=0;y<cyClient;y=+16)
应该是for(int y=0;y<cyClient;y+=16)
yiruirui0507 2011-01-19
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 happyparrot 的回复:]
调试一下普通画图时,cxClient和cyClient的值
另外在定时器中,你怎么写if(radius<16)
{radius++;}
else
{radius=0;}

啥意思?
[/Quote]

Ellipse(hdc,x,y,x+radius,y+radius)
我不想让他画的太大,所以限制一下,然后再又从头画。
快乐鹦鹉 2011-01-19
  • 打赏
  • 举报
回复
调试一下普通画图时,cxClient和cyClient的值
另外在定时器中,你怎么写if(radius<16)
{radius++;}
else
{radius=0;}

啥意思?

16,550

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧