1.要实现文件双击打开,需要在注册表中将文件类型与要打开文件的程序相关联。
在HKEY_CURRENT_USER\Software\Classes 或者
HKEY_LOCAL_MACHINE\Software\Classes 下创建.xxxx/shell/open/command cammand 下创建默认值"程序全路径" "%1"
如下图,对于自定义的.fgh文件,在Classes下
后面的文件路径必须用\,使用/会失败,原因不清楚,文件路径需用""括起来,后面的%1也需要,否则会失败。
qt 代码
QSettings *reg = new QSettings("HKEY_CURRENT_USER\\Software\\Classes",
QSettings::NativeFormat);
QString appPath = QCoreApplication::applicationDirPath();
appPath.replace("/", "\\");
#ifdef QT_DEBUG
appPath += "\\FlowEditord.exe\" \"%1\"";
#else
appPath += "\\FlowEditor.exe\" \"%1\"";
#endif // QT_DEBUG
reg->setValue(".fgh/shell/open/command/Default", "\""+appPath);
delete reg;
2.双击文件后在一个应用程序实例中打开
首先需要找到已经打开的应用程序主窗体,方法有多种,使用Windows API FindWiddow;
获取到窗体句柄后,从main函数的参数中获取到 传入的文件全路径,在argv的第二个位置,第一个是应用程序本身的名字。
将文件名传入找到的窗体,使用SendMessage,COPYDATASTRUCT,处理WM_COPYDATA 消息,按需要的方式打开文件
qt 代码
找到已存在的实例并发送文件位置信息
<span style="white-space:pre"> </span>QString ss = QString::fromLocal8Bit("流程编辑器");
std::wstring st = ss.toStdWString();
const wchar_t* se = st.c_str();
HWND hwnd = ::FindWindow(NULL, se);
if (hwnd)
{
if (argc > 1)
{
COPYDATASTRUCT cpd;
cpd.dwData = 0;
//cpd.cbData = str.size()+1;
ss = QString::fromLocal8Bit(argv[1]);
QByteArray bt = ss.toLocal8Bit();
cpd.cbData = bt.length() + 1;
cpd.lpData = bt.data();
::SendMessageW(hwnd, WM_COPYDATA, NULL, (LPARAM)&cpd);
}
return 0;
}
接收消息并打开文件
bool FlowEditor::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
MSG* msg = reinterpret_cast<MSG*>(message);
int msgType = msg->message;
if (msg->message == WM_COPYDATA)
{
COPYDATASTRUCT * p = reinterpret_cast<COPYDATASTRUCT*>(msg->lParam);
char *t = static_cast<char*>(p->lpData);
dragOpenFile(QString::fromLocal8Bit(t));
}
return false;
}