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;
}