求助---关于API双缓冲的

skyince 2011-06-11 12:18:03
//Main.cpp---------------------------

#include <windows.h>
#include "ChessBoard.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

static TCHAR szAppName[] = TEXT ("五子棋") ;

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) ;/*NULL;*/

wndclass.lpszMenuName= NULL ;

wndclass.lpszClassName= szAppName ;



if (!RegisterClass (&wndclass))

{

MessageBox (NULL, TEXT ("Program requires Windows NT!"),

szAppName, MB_ICONERROR) ;

return 0 ;

}



hwnd = CreateWindow (szAppName, TEXT ("Line Demonstration"),

WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,

CW_USEDEFAULT, CW_USEDEFAULT,

800,600,

NULL, NULL, hInstance,NULL) ;



ShowWindow (hwnd, iCmdShow) ;

UpdateWindow (hwnd) ;



while (GetMessage (&msg, NULL, 0, 0))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

return msg.wParam ;

}

int Mx,My;


LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{


//棋盘
static int cxClient, cyClient ;//棋盘长宽
RECT rt;
GetClientRect(hwnd,&rt);
cxClient=rt.right;
cyClient=rt.bottom;
Board Bboard(cxClient,cyClient);


HDC hdc;

PAINTSTRUCT ps ;



switch (message)

{
case WM_MOUSEMOVE://获取鼠标位置
Mx=LOWORD(lParam);
My=HIWORD(lParam);


InvalidateRect(hwnd,&rt,TRUE);

return 0;


case WM_PAINT:

hdc = BeginPaint (hwnd, &ps) ;
Bboard.DrawBoard(hdc,hwnd);//显示棋盘
Bboard.MouseLocation(hdc,Mx,My,hwnd);//鼠标位置
EndPaint (hwnd, &ps) ;
return 0 ;


case WM_DESTROY://销毁窗口

PostQuitMessage (0) ;

return 0 ;

}

return DefWindowProc (hwnd, message, wParam, lParam) ;

}

//----ChessBoard.h
#include <iostream>
#include <Windows.h>
#include "DoubleBuffering.h"
using namespace std;
static int Bsize=500;
class Board// 棋盘
{
public:

Board(/*HDC hdc,*/int Brow,int Bline);
//~Board();
void DrawBoard(HDC hdc,HWND hwnd);//绘制棋盘
void MouseLocation(HDC hdc,int PtX,int PtY,HWND hwnd);



//记录鼠标坐标:
//1:判断可否下棋
//BOOL Chess_next();



private:


//双缓冲

HDC hdcmem;// 内存设备
HBITMAP hbm;
HBITMAP holdbm;//hbm代表hdcmem中的显示平面(画布),holdbm保存旧的显示屏幕



//RECT rt;
RECT Brt;
HPEN hOutPen,hOldOutPen,hInPen,hOldInPen;


int row;// 行
int line;// 列
int Xboundary;// 宽边界
int Yboundary;//高边界
};


//ChessBoard.cpp

#include "ChessBoard.h"
#include <Windows.h>



Board::Board(/*HDC hdc,HWND hwnd,*/int Brow,int Bline)
{

line=Brow;
row=Bline;



Xboundary=(line-Bsize)/2;//宽边界
Yboundary=(row-Bsize)/2;//高边界



}

void Board::DrawBoard(HDC hdc,HWND hwnd)

{


hdcmem=CreateCompatibleDC(hdc);
hbm=CreateCompatibleBitmap(hdc, line, row);
holdbm=(HBITMAP)SelectObject(hdcmem, hbm);


GetClientRect(hwnd,&Brt);

FillRect( hdcmem, &Brt, (HBRUSH)(WHITE_BRUSH) );



hOutPen=CreatePen(PS_SOLID,5,RGB(255,255,0));
hOldOutPen=(HPEN)SelectObject(hdc,hOutPen);


Rectangle(hdc,Xboundary,Yboundary,Xboundary+Bsize,Yboundary+Bsize);//绘制外框
SelectObject(hdc,hOldOutPen);
DeleteObject(hOutPen);





//绘制内线。



hInPen=CreatePen(PS_SOLID,2,RGB(50,0,0));
hOldInPen=(HPEN)SelectObject(hdc,hInPen);



for (int x=Xboundary;x<=Xboundary+Bsize;x+=25) // 列
{
MoveToEx(hdc,x,Yboundary,NULL);
LineTo(hdc,x,Yboundary+Bsize);


}


for (int y=Yboundary;y<=Yboundary+Bsize;y+=25)//行
{
MoveToEx(hdc,Xboundary,y,NULL);
LineTo(hdc,Xboundary+Bsize,y);

}


BitBlt(hdc,0,0,line,row,hdcmem,0,0,SRCCOPY);//把图形绘制到桌面

SelectObject(hdcmem, holdbm);
DeleteDC(hdcmem);
DeleteObject(hbm);

SelectObject(hdc,hOldOutPen);
SelectObject(hdc,hOldInPen);

DeleteObject(hOldInPen);
DeleteObject(hOldOutPen);




}


void Board::MouseLocation(HDC hdc,int PtX,int PtY,HWND hwnd)
{

TCHAR MOUSE_Point[100];

HPEN MOUSE_Pen,MOUSE_OldPen;
MOUSE_Pen=CreatePen(PS_SOLID,10,RGB(0,0,0));
MOUSE_OldPen=(HPEN)SelectObject(hdc,MOUSE_Pen);


wsprintf(MOUSE_Point,TEXT("x value is %d, y value is %d"),PtX,PtY);
TextOut(hdc,0,0,MOUSE_Point,lstrlen(MOUSE_Point));

SelectObject(hdc,MOUSE_OldPen);
DeleteObject(MOUSE_Pen);

}





////求助啊啊---用了双缓冲画面还是在闪的----求修改

...全文
76 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
就想叫yoko 2011-06-11
  • 打赏
  • 举报
回复
MFC只在以前学习C++的时候接触过一点
记得那是遇到闪的问题先是用了双缓冲 并没有解决问题
后来在OnEraseBk()重绘背景那个函数, 名字不一定对 做了些处理 就不闪了

菜鸟愚见 作为参考吧
建议你去VC区问问
那边解决问题挺快的
ryfdizuo 2011-06-11
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 q191201771 的回复:]

事实上很多时候闪的原因不在双缓冲
而在于背景的重绘
VC的问题去VC区问问吧
[/Quote]
多次直接绘制屏幕会出现闪烁的。。。
就想叫yoko 2011-06-11
  • 打赏
  • 举报
回复
事实上很多时候闪的原因不在双缓冲
而在于背景的重绘
VC的问题去VC区问问吧
ryfdizuo 2011-06-11
  • 打赏
  • 举报
回复
双缓存原理是先把所有的显示内容多次写到一个内存DC上,然后一次性显示到屏幕。
而不是多次直接拷贝到屏幕。

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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