在API中怎么解决鼠标拉动图片时的闪烁白条(纯API代码)网上有很多关于这个的问题 但是都是MFC的代码 都是说的双重缓存技术,但是我不知道在纯API怎么实现我现在正在学API 还没有接触MFC 所以看不懂MFC代码//以下是我的代码 麻烦大家帮我 这代码应该怎么改才不会闪烁
---------------------------------
#include <windows.h>
#include <stdio.h>
#include "resource.h"
HDC hdc,hdcBit;//定义图形句柄
HBITMAP hBm;
BITMAP bm;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam);//申明窗口处理函数//-------初始化窗口类---------------------------------
int APIENTRY WinMain(
HINSTANCE hInstance, //应用程序当前实例句柄
HINSTANCE hPrevInstance, //应用程序其他实例句柄
LPTSTR lpCmdLine, //指向程序命令行参数的指针
int nCmdShow //应用程序开始执行时窗口显示方式的整数值标识
)
{
HWND hwnd; //定义窗口句柄
MSG Msg; //定义消息的类
WNDCLASS wndclass; //定义窗口的类
char lpszClassName[]="窗口"; //定义窗口类名
char lpszTitle[]="我的窗口"; //定义窗口标题
wndclass.style=0; //设置窗口样式
wndclass.lpfnWndProc=WndProc;//定义窗口处理函数
wndclass.cbClsExtra=0;//窗口类无扩展
wndclass.cbWndExtra=0;//窗口实例无扩展
wndclass.hInstance=hInstance;//当前实例句柄
wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);//窗口最小化图标为缺省
wndclass.hCursor=LoadCursor(hInstance,MAKEINTRESOURCE(IDB_BITMAP));//窗口采用箭头光标
wndclass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);//窗口背景色为白色
wndclass.lpszMenuName="Menu";//窗口中无菜单
wndclass.lpszClassName=lpszClassName;//定义窗口类名
//-------初始化窗口类---------------------------------
//-------注册窗口---------------------------------
if(!RegisterClass(&wndclass)) //注册窗口
{
MessageBeep(0); //如果注册失败,则发出警告
return FALSE; //返回为假
}
//-------注册窗口---------------------------------
//-------创建窗口---------------------------------
hwnd=CreateWindow(
lpszClassName, //窗口类名
lpszTitle, //窗口标题名
WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL, //创建窗口的样式,WS_VSCROLL垂直滚动条,WS_HSCROLL水平滚动条
100,100, //窗口左上角坐标
800,600, //窗口宽度和度高
NULL, //该窗口的父窗口句柄
NULL, //窗口主菜单句柄
hInstance, //创建窗口的应用程序当前句柄
NULL //指向一个传递给窗口的参数值的指针
);
//-------创建窗口---------------------------------
hBm=LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP));
GetObject(hBm,sizeof(BITMAP),(LPVOID)&bm);
ShowWindow(hwnd,nCmdShow); //显示窗口函数
UpdateWindow(hwnd); //刷新窗口函数
//-------消息循环---------------------------------
while (GetMessage(&Msg,NULL,0,0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return (int) Msg.wParam;
}
//-------消息循环---------------------------------//-------窗口处理函相数------------------------------
LRESULT CALLBACK WndProc(HWND hwnd, UINT message,WPARAM wParam, LPARAM lParam)
{
static HINSTANCE hInst ;
PAINTSTRUCT ps;//定义指向包含绘图信息的结构变量
static POINT nPos,oPos,aPos;
static BOOL ndw=FALSE;
char str[20];
switch(message)
{
case WM_CREATE:
hdc=GetDC(hwnd);
hdcBit=CreateCompatibleDC(hdc);
hBm=CreateCompatibleBitmap(hdc,bm.bmWidth,bm.bmHeight);//双重缓存
hInst = ((LPCREATESTRUCT)lParam)->hInstance;// 获取程序实例句柄
SetClassLong(hwnd, GCL_HICON, (LONG)LoadIcon(hInst, MAKEINTRESOURCE(IDB_BITMAP)));
SetCursor(LoadCursor(hInst, MAKEINTRESOURCE(IDB_BITMAP)));
ReleaseDC(hwnd,hdc);
break;
case WM_LBUTTONDOWN:
if(LOWORD(lParam)>=aPos.x&&LOWORD(lParam)<=aPos.x+bm.bmWidth&&HIWORD(lParam)>=aPos.y&&HIWORD(lParam)<=aPos.y+bm.bmHeight)
{
SetCursor(LoadCursor(hInst,MAKEINTRESOURCE(IDC_CURSOR)));
nPos.x=LOWORD(lParam);
nPos.y=HIWORD(lParam);
ndw=TRUE;
}
break;
case WM_RBUTTONDOWN:
InvalidateRect(hwnd,NULL,TRUE);
break;
case WM_LBUTTONUP:
if(ndw==TRUE)
{
aPos.x=aPos.x+oPos.x;
aPos.y=aPos.y+oPos.y;
ndw=FALSE;
SetCursor(LoadCursor(NULL,IDC_ARROW));
InvalidateRect(hwnd,NULL,TRUE);
}
break;
case WM_MOUSEMOVE:
if(ndw==TRUE)
{
oPos.x=LOWORD(lParam)-nPos.x;
oPos.y=HIWORD(lParam)-nPos.y;
InvalidateRect(hwnd,NULL,TRUE);
ReleaseDC(hwnd,hdc);
}
else
SetCursor(LoadCursor(NULL,IDC_ARROW));
if(LOWORD(lParam)>=aPos.x&&LOWORD(lParam)<=aPos.x+bm.bmWidth&&HIWORD(lParam)>=aPos.y&&HIWORD(lParam)<=aPos.y+bm.bmHeight)
SetCursor(LoadCursor(hInst,MAKEINTRESOURCE(IDC_CURSOR)));
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps); //开始绘图
SelectObject(hdcBit,hBm);
if(ndw==FALSE)
StretchBlt(hdc,aPos.x,aPos.y,bm.bmWidth,bm.bmHeight,hdcBit,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
else
StretchBlt(hdc,aPos.x+oPos.x,aPos.y+oPos.y,bm.bmWidth,bm.bmHeight,hdcBit,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
sprintf(str,"%d,%d",aPos.x,aPos.y);
TextOut(hdc,0,0,str,strlen(str));
EndPaint(hwnd,&ps);//结束绘图
return 0;
case WM_DESTROY://退出消息
DeleteObject(hdcBit);
PostQuitMessage(0);//退出处理函数
return 0;
default: //缺省消息处理函数
return DefWindowProc(hwnd,message,wParam,lParam);
}
return(0);
}
//-------窗口处理函相数------------------------------
---------------------------------
#include <windows.h>
#include <stdio.h>
#include "resource.h"
HDC hdc,hdcBit;//定义图形句柄
HBITMAP hBm;
BITMAP bm;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam);//申明窗口处理函数//-------初始化窗口类---------------------------------
int APIENTRY WinMain(
HINSTANCE hInstance, //应用程序当前实例句柄
HINSTANCE hPrevInstance, //应用程序其他实例句柄
LPTSTR lpCmdLine, //指向程序命令行参数的指针
int nCmdShow //应用程序开始执行时窗口显示方式的整数值标识
)
{
HWND hwnd; //定义窗口句柄
MSG Msg; //定义消息的类
WNDCLASS wndclass; //定义窗口的类
char lpszClassName[]="窗口"; //定义窗口类名
char lpszTitle[]="我的窗口"; //定义窗口标题
wndclass.style=0; //设置窗口样式
wndclass.lpfnWndProc=WndProc;//定义窗口处理函数
wndclass.cbClsExtra=0;//窗口类无扩展
wndclass.cbWndExtra=0;//窗口实例无扩展
wndclass.hInstance=hInstance;//当前实例句柄
wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);//窗口最小化图标为缺省
wndclass.hCursor=LoadCursor(hInstance,MAKEINTRESOURCE(IDB_BITMAP));//窗口采用箭头光标
wndclass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);//窗口背景色为白色
wndclass.lpszMenuName="Menu";//窗口中无菜单
wndclass.lpszClassName=lpszClassName;//定义窗口类名
//-------初始化窗口类---------------------------------
//-------注册窗口---------------------------------
if(!RegisterClass(&wndclass)) //注册窗口
{
MessageBeep(0); //如果注册失败,则发出警告
return FALSE; //返回为假
}
//-------注册窗口---------------------------------
//-------创建窗口---------------------------------
hwnd=CreateWindow(
lpszClassName, //窗口类名
lpszTitle, //窗口标题名
WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL, //创建窗口的样式,WS_VSCROLL垂直滚动条,WS_HSCROLL水平滚动条
100,100, //窗口左上角坐标
800,600, //窗口宽度和度高
NULL, //该窗口的父窗口句柄
NULL, //窗口主菜单句柄
hInstance, //创建窗口的应用程序当前句柄
NULL //指向一个传递给窗口的参数值的指针
);
//-------创建窗口---------------------------------
hBm=LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP));
GetObject(hBm,sizeof(BITMAP),(LPVOID)&bm);
ShowWindow(hwnd,nCmdShow); //显示窗口函数
UpdateWindow(hwnd); //刷新窗口函数
//-------消息循环---------------------------------
while (GetMessage(&Msg,NULL,0,0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return (int) Msg.wParam;
}
//-------消息循环---------------------------------//-------窗口处理函相数------------------------------
LRESULT CALLBACK WndProc(HWND hwnd, UINT message,WPARAM wParam, LPARAM lParam)
{
static HINSTANCE hInst ;
PAINTSTRUCT ps;//定义指向包含绘图信息的结构变量
static POINT nPos,oPos,aPos;
static BOOL ndw=FALSE;
char str[20];
switch(message)
{
case WM_CREATE:
hdc=GetDC(hwnd);
hdcBit=CreateCompatibleDC(hdc);
hBm=CreateCompatibleBitmap(hdc,bm.bmWidth,bm.bmHeight);//双重缓存
hInst = ((LPCREATESTRUCT)lParam)->hInstance;// 获取程序实例句柄
SetClassLong(hwnd, GCL_HICON, (LONG)LoadIcon(hInst, MAKEINTRESOURCE(IDB_BITMAP)));
SetCursor(LoadCursor(hInst, MAKEINTRESOURCE(IDB_BITMAP)));
ReleaseDC(hwnd,hdc);
break;
case WM_LBUTTONDOWN:
if(LOWORD(lParam)>=aPos.x&&LOWORD(lParam)<=aPos.x+bm.bmWidth&&HIWORD(lParam)>=aPos.y&&HIWORD(lParam)<=aPos.y+bm.bmHeight)
{
SetCursor(LoadCursor(hInst,MAKEINTRESOURCE(IDC_CURSOR)));
nPos.x=LOWORD(lParam);
nPos.y=HIWORD(lParam);
ndw=TRUE;
}
break;
case WM_RBUTTONDOWN:
InvalidateRect(hwnd,NULL,TRUE);
break;
case WM_LBUTTONUP:
if(ndw==TRUE)
{
aPos.x=aPos.x+oPos.x;
aPos.y=aPos.y+oPos.y;
ndw=FALSE;
SetCursor(LoadCursor(NULL,IDC_ARROW));
InvalidateRect(hwnd,NULL,TRUE);
}
break;
case WM_MOUSEMOVE:
if(ndw==TRUE)
{
oPos.x=LOWORD(lParam)-nPos.x;
oPos.y=HIWORD(lParam)-nPos.y;
InvalidateRect(hwnd,NULL,TRUE);
ReleaseDC(hwnd,hdc);
}
else
SetCursor(LoadCursor(NULL,IDC_ARROW));
if(LOWORD(lParam)>=aPos.x&&LOWORD(lParam)<=aPos.x+bm.bmWidth&&HIWORD(lParam)>=aPos.y&&HIWORD(lParam)<=aPos.y+bm.bmHeight)
SetCursor(LoadCursor(hInst,MAKEINTRESOURCE(IDC_CURSOR)));
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps); //开始绘图
SelectObject(hdcBit,hBm);
if(ndw==FALSE)
StretchBlt(hdc,aPos.x,aPos.y,bm.bmWidth,bm.bmHeight,hdcBit,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
else
StretchBlt(hdc,aPos.x+oPos.x,aPos.y+oPos.y,bm.bmWidth,bm.bmHeight,hdcBit,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
sprintf(str,"%d,%d",aPos.x,aPos.y);
TextOut(hdc,0,0,str,strlen(str));
EndPaint(hwnd,&ps);//结束绘图
return 0;
case WM_DESTROY://退出消息
DeleteObject(hdcBit);
PostQuitMessage(0);//退出处理函数
return 0;
default: //缺省消息处理函数
return DefWindowProc(hwnd,message,wParam,lParam);
}
return(0);
}
//-------窗口处理函相数------------------------------
解决方案 »
- 开发自己的msn遇到问题了。。哎,高手速救。。
- 工作线程与主线程通讯有哪几种方式?
- MFC视图中添加树型复选框
- 初学者:请问如果我想应用程序里调用windows的计算器,并返回计算结果到应用程序中,该怎么实现,要知道那些技术?
- 想写一个NT的服务程序,不想要界面
- 哪位兄弟可以提供一个BoundsChecker for vc的下载地址。
- 请教大侠在SQL Server中,用Image字段存储和读取一个图片文件,在VC中怎么写代码?
- 我想把树型控件的信息(包括各节点、叶子的信息)按照树型结构保存在一个数据类型(比如数组结构)中,请指教!!
- windwos如何和交换机通过串口通讯,在不知道协议的情况下
- 如何察看SDK编程中WMI类的Provider类型???
- 怎么才能做到禁止进程的启动?
- 图像的自动切割
比较实用的解决方法是在原使用InvalidateRect的地方直接绘制(别怕麻烦)。可以定义一个函数OnDraw(HDC hdc);在WM_PAINT、WM_MOUSEMOVE等地方直接调用OnDraw
我那样做了 是不闪烁了 但是鼠标动图片经过的所有位置会留下以前的痕迹
意思就是图片以外的所有区域没有被刷新
我想 如果是不用刷新根本解决不了这个问题
只有解决了刷新的时候产生的闪烁才能根本解决
希望会的帮帮小弟!
我那样做了 是不闪烁了 但是鼠标动图片经过的所有位置会留下以前的痕迹
意思就是图片以外的所有区域没有被刷新
你说的方法也相当于是把InvalidateRect的最后个值设置为FALSE的效果
我想 如果是不用刷新根本解决不了这个问题
InvalidateRect(hwnd,&rect,FALSE)也不能解决问题
只有解决了刷新的时候产生的闪烁才能根本解决
希望会的帮帮小弟!
好好体会一下InvalidateRect函数吧。会给你得绘图带来高效率的。
第二个参数设为NULL后,标记的是整个客户区无效,均需重绘. 写代码时会比较简单,但它是利用系统的消息机制, 通知系统准备重绘. 这种方法即使后面紧跟UpdateWindow, 也必须要等到系统处理完相关消息后才能生效, 如果背景反差大且绘制过程复杂,闪烁很难避免.在WM_SIZE/WM_VSCROLL/WM_HSCROLL等消息的处理中,先GetDC然后直接绘制, 虽然增加了额外的代码量, 但这是高效的方法(不必等系统发消息后再处理, 且在多数情况下不必重绘整个客户区)