本篇《Windows界面编程第七篇文件拖拽(文件拖放)》来介绍如何为程序添加文件拖拽(文件拖放)操作,文件拖拽(文件拖放)操作可以归类到Windows程序的界面操作,因此也将这篇文章放到Windows界面编程系列中。
文件拖拽(文件拖放)功能能有效提高用户体验,在VC++中要让程序支持文件拖拽功能,主要使用三个函数——DragAcceptFiles,DragQueryFile和DragFinish。下面先来介绍这三个函数(为了更加好学习英语,函数介绍尽可能会使用英语)。
一.DragAcceptFiles
函数功能:Registers whether a window accepts dropped files. An application that calls DragAcceptFiles with the fAccept parameter set to TRUE has identified itself as able to process the WM_DROPFILES message from File Manager.
函数原型:
//By MoreWindows-(http://blog.csdn.net/MoreWindows)
VOIDDragAcceptFiles(
HWNDhWnd,
BOOL fAccept
);
参数说明:
第一个参数hWnd:
The identifier of the window that is registering whether it will accept dropped files.
第二个参数fAccept:
A value that indicates if the window identified by the hWnd parameter accepts dropped files. This value is TRUE to accept dropped files or FALSE to discontinue accepting dropped files.
对于对话框程序,还可以通过选择其Properties->Extended Styles,点选Accept files选项即可。
一.DragQueryFile
函数功能:Retrieves the names of dropped files that result from a successful drag-and-drop operation.
函数原型:
//By MoreWindows-(http://blog.csdn.net/MoreWindows)
UINTDragQueryFile(
HDROPhDrop,
UINT iFile,
LPTSTRlpszFile,
UINTcch
);
参数说明:
第一个参数hDrop:
HDROP标识符,即响应函数中的wParam参数
第二个参数iFile::
待查询的文件索引号,从0开始。可以同时拖拽多个文件,因此就需要一个索引号来进行区分。如果该参数为0xFFFFFFFF,则该函数返回拖拽的文件的个数
第三个参数lpszFile:
用于存放文件名的缓冲区首地址
第四个参数cch:
缓冲区长度
函数返回值:若iFile为0xFFFFFFFF返回拖拽的文件个数,否则返回相应索引号的文件名长度。
第三个DragFinish
函数功能:Releases memory that the system allocated for use in transferring file names to the application.
函数原型:
//By MoreWindows-(http://blog.csdn.net/MoreWindows)
VOIDDragFinish(HDROPhDrop);
下面是示例程序代码,代码中有详细注释。(下载地址:http://download.csdn.net/detail/morewindows/5128654)
- // 文件拖拽<a href="http://blog.csdn.net/morewindows/article/details/8634451">http://blog.csdn.net/morewindows/article/details/8634451</a>
- //By MoreWindows-(http://blog.csdn.net/MoreWindows)
- // 第一步 #include <shellapi.h> #pragma comment(lib, "shell32.lib")
- // 第二步 DragAcceptFiles(hwnd, TRUE);
- // 第三步 UINT nFileNum = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);拖曳文件个数
- // 第四步 DragQueryFile(hDrop, i, strFileName, MAX_PATH);获得拖曳的文件名
- #include "stdafx.h"
- #include <vector>
- #include <cstring>
- usingnamespace std;
- // 文件拖拽第一步
- #include <shellapi.h>
- #pragma comment(lib, "shell32.lib")
- constchar szAppName[] = "文件拖拽_MoreWindows(http://blog.csdn.net/MoreWindows)";
- BOOL InitApplication(HINSTANCE hinstance,int nCmdShow);
- LRESULT CALLBACK WndProc(HWND hwnd,UINT message, WPARAM wParam,LPARAM lParam);
- int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
- {
- // TODO: Place code here.
- MSG msg;
- if (!InitApplication(hInstance, nCmdShow))
- {
- return 0;
- }
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return msg.wParam;
- return 0;
- }
- BOOL InitApplication(HINSTANCE hinstance,int nCmdShow)
- {
- HWND hwnd;
- WNDCLASS wndclass;
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = WndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = 0;
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = szAppName;
- if (!RegisterClass(&wndclass))
- {
- MessageBox(NULL, "Program Need Windows NT!", szAppName, MB_ICONERROR);
- return FALSE;
- }
- hwnd = CreateWindow(szAppName,
- szAppName,
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL,
- NULL,
- hinstance,
- NULL);
- if (hwnd == NULL)
- return FALSE;
- ShowWindow(hwnd, nCmdShow);
- UpdateWindow(hwnd);
- return TRUE;
- }
- LRESULT CALLBACK WndProc(HWND hwnd,UINT message, WPARAM wParam,LPARAM lParam)
- {
- static vector<string> s_vetFileNames;
- switch (message)
- {
- case WM_CREATE:
- // 文件拖拽第二步 DragAcceptFiles
- DragAcceptFiles(hwnd, TRUE);
- return 0;
- // 文件拖拽第三步 DragQueryFile and DragQueryFile
- case WM_DROPFILES:
- {
- HDROP hDrop = (HDROP)wParam;
- UINT nFileNum = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); // 拖拽文件个数
- char strFileName[MAX_PATH];
- for (int i = 0; i < nFileNum; i++)
- {
- DragQueryFile(hDrop, i, strFileName, MAX_PATH);//获得拖曳的文件名
- s_vetFileNames.push_back(strFileName);
- }
- DragFinish(hDrop); //释放hDrop
- InvalidateRect(hwnd, NULL, TRUE);
- }
- return 0;
- case WM_PAINT:
- {
- HDC hdc;
- PAINTSTRUCT ps;
- vector<string>::iterator pos;
- int i, y;
- hdc = BeginPaint(hwnd, &ps);
- // 显示拖拽的文件名
- y = 0;
- for (pos = s_vetFileNames.begin(); pos != s_vetFileNames.end(); pos++)
- {
- TextOut(hdc, 20, y, pos->c_str(), strlen(pos->c_str()));
- y += 30;
- }
- EndPaint(hwnd, &ps);
- }
- return 0;
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
运行结果截图如下,在桌面上选取了几个快捷方式然后拖到程序窗口中:
通过本文,可以看出要为程序添加文件拖拽(文件拖放)功能,只要四步即可。
第一步
#include <shellapi.h> #pragma comment(lib, "shell32.lib")
第二步
DragAcceptFiles(hwnd, TRUE);
第三步
UINT nFileNum = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);拖曳文件个数
第四步
DragQueryFile(hDrop, i, strFileName, MAX_PATH);获得拖曳的文件名
欢迎继续参考《Windows界面编程第八篇 listbox彩色显示隔行变色》