【100分】请教一下,你们双击打开文件的操作是不是多进程通信处理的?

maya8maya85 2020-05-15 12:16:22
最近遇到一个不太懂的事,但我觉得应该有不少人写过并且有一个相对普遍的方法去实现,然而我百度没有找到,所以在这里请教一下大佬们指导一下小弟,谢谢了
是这样的
文件类型已经关联好了,如果没启动程序,双击文件也能启动程序。
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
std::string targetfile = lpCmdLine; //注册文件类型后,双击对应文件类型,这个值将接收目标文件

//查找主窗体是否已经运行
HWND hwnd = ::FindWindow(NULL, _T("MainWnd"));
if (hwnd != NULL) {
//如果用户通过双击打开关联的文件,则尝试打开文件
if (targetfile.size()) {
//const char * tf = "你就是个god"; //成功
//const char * tf = targetfile.data(); //失败

//MessageBox(hwnd, tf, NULL, 0);//全部成功,正确显示双击的文件路径
::SendMessage(hwnd, WM_OPENTARGETFILE, 0, (LPARAM)tf);
}
return 0;
}
else {
//主窗体没运行,就运行主窗体
CMainWnd* pFrame = new CMainWnd;
if (pFrame == NULL) return 0;
pFrame->Create(NULL, _T("MainWnd"), UI_WNDSTYLE_FRAME, 0L, 0, 0, 990, 690);
pFrame->CenterWindow();
pFrame->ShowModal();
delete pFrame;

return 0;
}
}


这传值,就是把我双击那个文件的路径传到这个MainWnd里,这一步就难到我,看上面代码,我具体赋值是成功传值的,但用targetfile就不行了,不管是c_str()还是data()全部不能传,但弹出窗口的时候却都是正确的。问了一个也是写代码的,他比我了解一些,但也没写过这种,他说这里应该是多进程的,打开多少个文件就多少个进程,传不到值是因为跨进程了,要进程间通信,我想知道,大家在这里是怎么处理的,就是双击文件传值这里,是多进程通信吗?还是怎么传的,虚心求指导!
...全文
451 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
schlafenhamster 2020-05-27
  • 打赏
  • 举报
回复
调用
双击-》void CMainFrame::OnFileOpen()
{
//////
// other file
if(GetExeCommand(fullname,command))
{ // OK
if(!GoCommand(command))
{
CString prompt;
AfxFormatString1(prompt,IDS_BAD_COMMAND,fullname);
AfxMessageBox(prompt);
}
return;
}
/////////////
schlafenhamster 2020-05-27
  • 打赏
  • 举报
回复
以前写的不知道现在行不行

////
BOOL CMainFrame::GetExeCommand(char *fullname,char* command)
{// ""%1" 1*" for .bat file
// "xxx.exe %1"
// ""\a b\c\yyy.exe" /p %1"
char ext[40];
char pathname[MAX_PATH];
char exename[MAX_PATH];
char *at=0;
strcpy(pathname,fullname);
// must ".xxx"
if((at=strrchr(fullname,'.'))==NULL) return FALSE;
strcpy(ext,at);

char open_key[MAX_PATH];
DWORD openkeylen=MAX_PATH;
char shellname[MAX_PATH]="shell";
// under shell may be different "open","cplopen","Open with"...
BYTE extfile[MAX_PATH];
DWORD cbextfile=MAX_PATH;
DWORD dwType=REG_SZ;
HKEY hkey;
HKEY hsubkey;
// from ".xxx" get "xxxfile"
// C:\Users\Shen Hui\AppData\Roaming\Heinote\hnote.exe %1
// HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\. txt
DWORD dwErrorCode=RegOpenKeyEx(HKEY_CLASSES_ROOT,ext,0,KEY_READ,&hkey);
if (dwErrorCode != ERROR_SUCCESS)
{ // error not found
command[0]=0;
return FALSE;
}
else
{ // ".xxx" OK
// get "xxxfile"
dwErrorCode=RegQueryValueEx(hkey,NULL,0,&dwType,extfile,&cbextfile);
RegCloseKey(hkey);
char tmp[MAX_PATH];
sprintf(tmp,"%s\\%s",extfile,shellname);// "cppfile\\shell"
if (dwErrorCode == ERROR_SUCCESS)
{// "cppfile\\shell"
dwErrorCode=RegOpenKeyEx(HKEY_CLASSES_ROOT,tmp,0,KEY_READ,&hsubkey);
if (dwErrorCode == ERROR_SUCCESS)
{// "cppfile\\shell"
LONG enumErr=ERROR_SUCCESS;
DWORD j=0;
FILETIME ftLastWriteTime;
while (enumErr==ERROR_SUCCESS || enumErr==ERROR_MORE_DATA)
{
cbextfile=260;// re-init
openkeylen=MAX_PATH;// re-init
enumErr=RegEnumKeyEx(hsubkey,j,open_key,&openkeylen,
NULL,NULL,NULL,&ftLastWriteTime);
strcpy(tmp,open_key);
_strupr(tmp);
if(strstr(tmp,"OPEN")) // any "open"
{
sprintf(tmp,"%s\\%s\\%s\\command",extfile,shellname,open_key);// "cppfile\\shell"
break;
}
j++;
}
RegCloseKey(hsubkey);
if(enumErr!=ERROR_SUCCESS) return FALSE;
} // end with "shell" key
else
{ // no "shell" key
return FALSE;
}
// "shell\\...open...\\command"
dwErrorCode=RegOpenKeyEx(HKEY_CLASSES_ROOT,tmp,0,KEY_READ,&hsubkey);
cbextfile=260;// re-init
//extfile="%SystemRoot%\\system32\\NOTEPAD32.EXE %1"
dwErrorCode=RegQueryValueEx(hsubkey,NULL,0,&dwType,extfile,&cbextfile);
// if fullname contains space in its pathname ????
// if(strchr(fullname,' ')) sprintf(exename,"\"%s\"",fullname);
// else
strcpy(exename,fullname);
// replace "%SystemRoot%" to "c:\\winnt.400" //NT
if(strstr((char *)extfile,"%SystemRoot%"))
{
char windir[MAX_PATH];
GetWindowsDirectory(windir,MAX_PATH);
at=strchr((char *)extfile,'\\');// after "%SystemRoot%"

strcat(windir,at);
strcpy((char *)extfile,windir);
}
// parameterse
strcpy(tmp,(char*)extfile);
if(at=strstr(tmp,"%1"))
{
*(at+1)='s';// "%s"
sprintf(command,tmp,exename);
}
else
{
sprintf(command,"%s %s",tmp,exename);
}
RegCloseKey(hsubkey);
return TRUE;
}
else
{
command[0]=0;
return FALSE;
}
}
}
  • 打赏
  • 举报
回复
共享进城间传址是不行的,需要共享内存传数值过去,或者远程过程调用,传过去。手机无力,没法代码……
蒋晟 2020-05-20
  • 打赏
  • 举报
回复
单进程MFC嘛,去开源社区搜索MFC single instance就可以找到好多示例代码了。MFC虽然自己有EnableShellOpen但是这个是基于已经过时的DDE。新的代码建议用IDropTarget注册文件关联——用户选择了多个文件然后选择打开的时候,你的程序只会被启动一次,选择的文件名数组会在一个shell data object里面传给你,参考https://devblogs.microsoft.com/oldnewthing/20100503-00/?p=14183 当然这个只是针对资源管理器打开文件,用命令行还是能启动多个你的程序的实例的。单进程控制的话个人喜欢用共享内存通讯,用Mutex做同步。找窗口太不靠谱了,你选中两个文件同时打开,会出现找不到窗口的情况。
zgl7903 2020-05-17
  • 打赏
  • 举报
回复
maya8maya85 2020-05-16
  • 打赏
  • 举报
回复
引用 9 楼 zgl7903 的回复:
这种特性, MFC向导生成一个多文档MDI程序,就支持的。 主要的机理就是 Dynamic Data Exchange, WM_DDE_INITIATE WM_DDE_EXECUTE WM_DDE_TERMINATE
看来是个很基础的东西,该如何操作?
zgl7903 2020-05-16
  • 打赏
  • 举报
回复
这种特性, MFC向导生成一个多文档MDI程序,就支持的。 主要的机理就是 Dynamic Data Exchange, WM_DDE_INITIATE WM_DDE_EXECUTE WM_DDE_TERMINATE
zgl7903 2020-05-15
  • 打赏
  • 举报
回复
WM_COPYDATA 也可以参考下 Using Data Copy
zgl7903 2020-05-15
  • 打赏
  • 举报
回复
跨进程,可以考虑使用剪切板
孤客天涯 2020-05-15
  • 打赏
  • 举报
回复
先要
//允许用户通过Windows的文件管理器打开数据文件
EnableShellOpen():
然后自己搜索RegisterShellFileTypes
maya8maya85 2020-05-15
  • 打赏
  • 举报
回复
引用 6 楼 zgl7903 的回复:
引用 4 楼 maya8maya85 的回复:
[quote=引用 2 楼 zgl7903 的回复:] 跨进程,可以考虑使用剪切板
你的意思是说,的确是用多进程的,同时打开10文件,就有10个进程?你做过打开文件吗?
没太理解你的意思, 多个进程弹出文件打开对话框?[/quote] 其实这种情况现实中非常多,随便捡个说吧。[word也是,photoshop也是,太多了,但大家好像都没讨论过这个,可能是太简单了] 像.url文件,是个网址的快捷方式,双击就是启动浏览器,然后创建一个标签页进行打开,对吧? 好,现在的情况是浏览器已经启动了,并且已经打开了一个网址,没错吧? 现在用户又双击了另一个.url文件,浏览器又会通过新建标签页打开一个网址,两个标签页, 两个.url, 对吧? 好了,问题就是, 1,双击.url的时候,浏览器是如何把接收的这个.url的路径从程序入口传到处理函数的呢?SendMessage么? 2,这两个标签页之间,是进程与进程的关系吗?如果是这样的话,那传送.url的路径就应该是进程间通信,而不是SendMessage了?我这样理解,正确吗? 3,如果没那么复杂,win32有自带的方法,求具体代码或链接
zgl7903 2020-05-15
  • 打赏
  • 举报
回复
引用 4 楼 maya8maya85 的回复:
引用 2 楼 zgl7903 的回复:
跨进程,可以考虑使用剪切板
你的意思是说,的确是用多进程的,同时打开10文件,就有10个进程?你做过打开文件吗?
没太理解你的意思, 多个进程弹出文件打开对话框?
maya8maya85 2020-05-15
  • 打赏
  • 举报
回复
引用 1 楼 孤客天涯 的回复:
先要 //允许用户通过Windows的文件管理器打开数据文件 EnableShellOpen(): 然后自己搜索RegisterShellFileTypes
感谢你的回复,我的程序是win32, 添加了头文件afxwin.h,依然不能使用这两个函数 还有的就是,这几个函数的放置位置问题,我的入口函数是APIENTRY WinMain,能不能在我的代码上修改一下,具体一点,如果了解DragAcceptFiles(),看能不能一起改改,多加分
maya8maya85 2020-05-15
  • 打赏
  • 举报
回复
引用 2 楼 zgl7903 的回复:
跨进程,可以考虑使用剪切板
你的意思是说,的确是用多进程的,同时打开10文件,就有10个进程?你做过打开文件吗?

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧