vc实现拖放控件

  • 格式:doc
  • 大小:177.50 KB
  • 文档页数:5

基于对话框的文件拖拽载入2011年4月7日梁昭发表评论阅读评论不知道你是否对QQ文件传输比较好奇?将文件拖入对话窗口,就可以实现文件的传输...其实在MFC中实现起来比较简单,在Windows中已经将消息封装好了。

这一节我们主要来学习一下基于对话框的文件拖拽功能!(1)最容易出错且较易遗忘的一步:选中对话框的属性"Accept files",细心一点容易发现,基本上所有的控件都有这个属性,注意只要将对话框的这个属性设置就行了,其余控件的属性不要进行设置。

否则主窗口的Accept files可能不起作用。

(2)将对话框的WM_DropFiles消息映射添加进来,(3)使用Win32 API可以轻易地在自己的GUI程序中加入拖放支持。

你需要了解这样几个函数DragAcceptFiles函数原型:VOID DragAcceptFiles(HWND hWnd, BOOL fAccept);此函数告诉Windows窗口hWnd是否接受从shell拖放过来的文件,fAccept=TRUE表示接受拖放。

这意味着窗口hWnd必须能够处理WM_DROPFILES消息。

DragFinish函数原型:VOID DragFinish(HDROP hDrop);在Drag-and-Drop过程完成时调用,从而允许shell释放为传递文件名而开辟的内存空间。

hDrop是WM_DROPFILES消息的WParam参数。

DragQueryFile函数原型:UINT DragQueryFile(HDROP hDrop, UINT iFile, LPTSTR lpszFile, UINT cch);此函数用来获取拖放的文件名。

hDrop是WM_DROPFILES消息的WParam参数,lpszFile是用于容纳文件名的缓冲区,cch是该缓冲区的大小。

设置iFile=0xFFFFFFFF的话,此函数返回拖放的文件总数,记为count。

设置iFile为区间[0, count)之间的任一整数就可以在lpszFile中得到序号为iFile的文件名,这个序号和用户在shell中点选文件图标的顺序有关。

DragQueryPoint 函数原型:BOOL DragQueryPoint(HDROP hDrop, LPPOINT lppt);此函数用来检索拖放时鼠标释放点的坐标,lppt是用来容纳鼠标坐标的结构。

因此,你必须首先为需要接受拖放的窗口建立消息映射,使其可以处理WM_DROPFILES消息,在VCL 或MFC中建立消息映射可以用BEGIN_MESSAGE_MAP宏。

此外,你必须在程序的主逻辑中调用DragAcceptFiles函数,向系统注册此窗口是否接受拖放。

void CDragFileDlgDlg::OnDropFiles(HDROP hDropInfo){// TODO: Add your message handler code here and/or call default CPoint pt;DragQueryPoint(hDropInfo,&pt);CRect leftrect,rightrect;//m_pic1.GetClientRect(&leftrect);m_pic1.GetWindowRect(&leftrect);ScreenToClient(&leftrect);m_pic2.GetWindowRect(&rightrect);ScreenToClient(&rightrect);int count;char filePath[200];count = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);//CBitmap bitmap;if(PtInRect(&leftrect,pt)){if(count==1){DragQueryFile(hDropInfo, 0, filePath, sizeof(filePath)); m_pic1.SetBitmap((HBITMAP)::LoadImage(::AfxGetInstanceHandle(), filePath,IMAGE_BITMAP,leftrect.Width(),leftrect.Height(),LR_LOADFROMFILE|LR_C REATEDIBSECTION));InvalidateRect(leftrect);}}else if(PtInRect(&rightrect,pt)){if(count==1){DragQueryFile(hDropInfo, 0, filePath, sizeof(filePath));m_pic2.SetBitmap((HBITMAP)::LoadImage(::AfxGetInstanceHandle(), filePath,IMAGE_BITMAP,rightrect.Width(),rightrect.Height(),LR_LOADFROMFILE|LR _CREATEDIBSECTION));InvalidateRect(rightrect);}}CDialog::OnDropFiles(hDropInfo);}需要注意几点:(1)获取控件在客户区的位置:使用m_pic1.GetClientRect(&leftrect);是获取不到的,这样获取的左上角坐标一定是(0,0),因此只能先用m_pic1.GetWindowRect(&leftrect);获取其在windows窗口的位置,然后使用ScreenToClient(&leftrect);将其映射为客户区坐标。

(2)picture/static控件加载外部图像使用CBitmap::LoadBitmap和CBitmap::SetBitmap是不能载入外部图像的,它只能载入位图资源内的图像,因此使用::LoadImage载入外部图片后可以实现。

默认情况下,图像放入picture/static控件之后要么控件随着图片的大小变化,要么图像被裁减。

但是通常情况下我们需要控件大小不变,只改变图像大小。

这个可以通过LoadImage来实现。

函数功能:该函数装载图标,光标,或位图。

函数原型:HANDLE LoadImage(HINSTANCE hinst,LPCTSTR lpszName,UINT uType,int cxDesired,int CyDesired,UINT fuLoad);hinst:处理包含被装载图像模块的特例。

若要装载OEM图像,则设此参数值为0。

lpszName:处理图像装载。

如果参数hinst为non-NULL ,而且参数fuLoad省略LR_LOADFROMFILE的值时,那么参数lpszName是一个指向保留在hinst模块中装载的图像资源名称,并以NULL为结束符的字符串。

如果参数hinst为空,并且LR_LOADFROMFILE被指定,那么这个参数低位字一定是被装载的OEM 图像标识的。

OEM图像标识符是在WINUSER.H头文件中定义的,下面列举出前缀的含义:OBM_ OEM:位图;OIC_OEM图标;OCR_OEM:光标。

如果参数fuLoad包含LR_LOADFROMFILE值,那么参数lpszName是包含有图像的文件名。

uType:指定被装载图像类型。

此参数可以为下列值,其含义如下:IMAGE_BITMAP:装载位图;IMAGE_CURSOR:装载光标;IMAGE_ICON:装载图标。

cxDesired:指定图标或光标的宽度,以像素为单位。

如果此参数为零并且参数fuLoad值为LR_DEFAULTSIZE,那么函数使用SM_CXICON或SM_CXCURSOR系统公制值设定宽度;如果此参数为零并且值LR_DEFAULTSIZE没有被使用,那么函数使用目前的资源宽度。

cyDesired:指定图标或光标的高度,以像素为单位。

如果此参数为零并且参数fuLoad值为LR_DEFAULTSIZE,那么函数使用SM_CXICON或SM_CXCURSOR系统公制值设定高度;如果此参数为零并且值LR_DEFAULTSIZE没有被使用,那么函数使用目前的资源高度。

fuLoad:根据下面复合值列表指定函数值,值含义如下:LR_DEFAULTCOLOR:缺省标志;它不作任何事情。

它的含义是“无LR_MONOCHROME”。

LR_CREATEDIBSECTION:当参数uType指定为IMAGE_BITMAP时,使得函数返回一个DIB部分位图,而不是一个兼容的位图。

这个标志在装载一个位图,而不是映射它的颜色到显示设备时非常有用。

LR_DEFAULTSIZE:若cxDesired或cyDesired未被设为零,使用系统指定的公制值标识光标或图标的宽和高。

如果这个参数不被设置且cxDesired或cyDesired被设为零,函数使用实际资源尺寸。

如果资源包含多个图像,则使用第一个图像的大小。

LR_LOADFROMFILE:根据参数lpszName的值装载图像。

若标记未被给定,lpszName的值为资源名称。

LW_LOADMAP3DCOLORS:查找图像的颜色表并且按下面相应的3D颜色表的灰度进行替换。

颜色替代:Dk Gray RGB(128,128,128)COLOR_3DSHADOW;Gray RGB(192,192,192)COLOR_3DFACELt Gray RGB(223,223,223)COLOR_3DLIGHTLR_LOADTRANSPARENT;找到图像中的一个像素颜色值并且根据颜色表中系统的缺省颜色值替代其相应接口的值。

图像中所有使用这种接口的像素的颜色都变为系统的缺省窗体颜色。

此至仅用来申请相应的颜色表。

若fuLoad包括LR_LOADTRANSPARENT和LR_LOADMAP3DCOLORS两个值,则LRLOADTRANSPARENT优先。

但是,颜色表接口由COLOR_3DFACE替代,而不是COLOR_WINDOW。

LR_MONOCHROME:装载黑白图。

LR_SHARED:若图像将被多次装载则共享。

如果LR_SHARED未被设置,则再向同一个资源第二次调用这个图像是就会再装载以便这个图像且返回不同的句柄。

不要对不同标准尺寸的图像使用LR_SHARED,装载后可能会有改变,或是从文件中被装载。