看到有帖子是这样说的,如果程序需要实现模拟双击后的行为,需要完整的模拟整个过程,还是ShellExecute即可(而需要从注册表中查到默认操作)?
Explorer.exe 先开始调用 ShellExecute 然后 在 注册表中的 Class Root 中查到 相应的处理程序 看是否用 DDE 或者调用 Shell Extension ,最终会调用 CreateProcess 创建 那个可执行文件的进程,传递 快捷方式指向 文件路径 的参数。
Explorer.exe 先开始调用 ShellExecute 然后 在 注册表中的 Class Root 中查到 相应的处理程序 看是否用 DDE 或者调用 Shell Extension ,最终会调用 CreateProcess 创建 那个可执行文件的进程,传递 快捷方式指向 文件路径 的参数。
BOOL CMainFrame::GetExeCommand(char *fullname,char* command)
{// ""%1" 1*" for .bat file
// "xxx.exe %1"
// ""\a b\c\yyy.exe" /p %1"
char ext[20];
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"
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;
}
}
}
//
//// creating process
BOOL CMainFrame::GoCommand(char *command,BOOL fwait /* FALSE */)
{
STARTUPINFO sinfo;
PROCESS_INFORMATION pinfo;
memset (&sinfo,0,sizeof(STARTUPINFO));
sinfo.cb=sizeof(STARTUPINFO);
sinfo.dwFlags|=STARTF_USESHOWWINDOW;
sinfo.wShowWindow=SW_SHOWNORMAL;
//BOOL fsuccess=0;
BOOL fsuccess=CreateProcess(NULL,//lpApplicationName
command, //lpCommanderLine
NULL, //lpProcessAttributes
NULL, //lpThreadAttributes
FALSE, //bInheritHandles
NORMAL_PRIORITY_CLASS,//dwCreationFlags
NULL, //lpEnvironment
NULL, //lpCurrentDirectory
&sinfo, //lpStartupInfo
&pinfo); //lpProcessInformation
...只供参考。
// "open with"
CPropPage4 pp4;// 需要显示所有的“.exe”
// title
sprintf(text,"%s open with",name);
CPSheet1 pps(text,this,0);
pps.AddPage((CPropPage4*)&pp4);
response=pps.DoModal();
if(response==IDOK)
{ // should return the ".exe"
command[0]=0;
strcpy(command,pp4.m_ExeFullName);
if(strlen(command))
{ // valid command
strcat(command," \"");
strcat(command,fullname);
strcat(command,"\"");// may have space
if(!GoCommand(command))
{
CString prompt;
AfxFormatString1(prompt,IDS_BAD_COMMAND,fullname);
AfxMessageBox(prompt);
}
}
}//CPropPage4比较长:VOID CPropPage4::FillOneItem(char *name,int count)
{
LVITEM lvi;
lvi.mask=LVIF_TEXT|LVIF_PARAM|LVIF_IMAGE;
lvi.cchTextMax=MAX_PATH;
lvi.iSubItem=0;
// "Open with"
int now=m_P4ListCtrl.GetItemCount();
SHFILEINFO sfi;
SHGetFileInfo(name,NULL,&sfi,sizeof(sfi),
SHGFI_DISPLAYNAME|SHGFI_ICON|SHGFI_SMALLICON);
if(sfi.hIcon==0) return;// not every one
int image=OpenWithImage.Add(sfi.hIcon);
// name only.path is in m_CommandArray[]
lvi.iItem=now;//index in list
lvi.lParam=count;//index in m_CommandArray[]
lvi.pszText=sfi.szDisplayName;// only filename no path !
lvi.iImage=image;
m_P4ListCtrl.InsertItem(&lvi);
}
////
VOID CPropPage4::PutInCommandArray(char *extention)
{
char tmp[MAX_PATH];
char OneExe[MAX_PATH]; int count=m_CommandArray.GetSize();// current
strcpy(tmp,extention);
strupr(tmp);
if(char *at=strstr(tmp,".EXE"))
{
memset(OneExe,0,MAX_PATH);
strncpy(OneExe,tmp,at-tmp+4);
if(OneExe[0]=='"') strcpy(OneExe,&OneExe[1]);
if(count==0)
{
m_CommandArray.Add(OneExe);
return;
}
// check if same
CString str1;
str1=CString(OneExe);
for (int j=0;j<count;j++)
{
if(str1.CompareNoCase(m_CommandArray[j])==0) break;//==
}
if (j==count) m_CommandArray.Add(OneExe);
}// ".exe"
}////
VOID CPropPage4::FillCommandArray()
{
char tmp[MAX_PATH]={0};
char tmp1[MAX_PATH]={0};
DWORD tmp_len=MAX_PATH;
DWORD total=0;
HKEY hkey;
DWORD dwType=REG_SZ;
DWORD dwErrorCode=RegOpenKeyEx(HKEY_CLASSES_ROOT,tmp,0,KEY_READ,&hkey);
if (dwErrorCode == ERROR_SUCCESS)
{ // Root OK
LONG enumErr=ERROR_SUCCESS;
FILETIME ftLastWriteTime;
char extention[MAX_PATH];
DWORD ext_len;
while (enumErr==ERROR_SUCCESS)
{ // serach ".xxx"
tmp[0]=0;
ext_len=MAX_PATH;// re-init
enumErr=RegEnumKeyEx(hkey,total,extention,&ext_len,
NULL,NULL,NULL,&ftLastWriteTime);
total++;
if(extention[0]=='.') //".xxx"
{ // get "xxxfile"
HKEY hsubkey;
strcat(tmp,extention);//".xxx"
dwErrorCode=RegOpenKeyEx(HKEY_CLASSES_ROOT,tmp,0,KEY_READ,&hsubkey);
if (dwErrorCode == ERROR_SUCCESS)
{ // ".xxx" Open
ext_len=MAX_PATH;// re-init
dwErrorCode=RegQueryValueEx(hsubkey,NULL,0,&dwType,(BYTE *)extention,&ext_len);
if (dwErrorCode == ERROR_SUCCESS)
{ // got "xxxfile"
RegCloseKey(hsubkey);
strcpy(tmp,extention);// "xxxfile"
strcat(tmp,"\\shell");//"xxxfile\\shell"
dwErrorCode=RegOpenKeyEx(HKEY_CLASSES_ROOT,tmp,0,KEY_READ,&hsubkey);
if (dwErrorCode == ERROR_SUCCESS)
{ // open "...\\shell" OK
LONG shellenum=ERROR_SUCCESS;
DWORD undershell=0;
HKEY hcomkey;
while (shellenum==ERROR_SUCCESS)
{
ext_len=MAX_PATH;// re-init
shellenum=RegEnumKeyEx(hsubkey,undershell,extention,&ext_len,
NULL,NULL,NULL,&ftLastWriteTime);
undershell++;
strcpy(tmp1,extention);
_strupr(tmp1);
if(strstr(tmp1,"OPEN")) // any "open"
{
strcat(tmp,"\\");
strcat(tmp,extention);
strcat(tmp,"\\command");
dwErrorCode=RegOpenKeyEx(HKEY_CLASSES_ROOT,tmp,0,KEY_READ,&hcomkey);
if (dwErrorCode == ERROR_SUCCESS)
{ // open "...\\command" OK
ext_len=MAX_PATH;// re-init
dwErrorCode=RegQueryValueEx(hcomkey,NULL,0,&dwType,(BYTE *)extention,&ext_len);
if (dwErrorCode == ERROR_SUCCESS)
{ // exe file name
RegCloseKey(hcomkey);
// AfxMessageBox(extention);
PutInCommandArray(extention);
}
}
}
} // end shell enum
RegCloseKey(hsubkey);
}
}
}
}
}// end while
RegCloseKey(hkey);
}
}
/////////////////////////////////////////////////////////////////////////////
// CPropPage4 message handlers
VOID CPropPage4::FillOpenWithList()
{
//init list
OpenWithImage.Create(16,16,ILC_COLOR8 | ILC_MASK,0,1);
m_P4ListCtrl.SetImageList(&OpenWithImage,LVSIL_SMALL);
m_P4ListCtrl.DeleteAllItems();
// report style
char text[MAX_PATH]={0};
memset(text,32,MAX_PATH); LVCOLUMN Column;
Column.mask=LVCF_FMT|LVCF_WIDTH|LVCF_TEXT;
Column.fmt=LVCFMT_LEFT;
Column.cx=300;
Column.pszText=text;
m_P4ListCtrl.InsertColumn(0,&Column);
m_CommandArray.RemoveAll();
//
FillCommandArray();
char OneExe[MAX_PATH]; int count=m_CommandArray.GetSize();
CWaitCursor wait;// display wait cursor
for (int j=0;j<count;j++)
{
strcpy(OneExe,m_CommandArray[j].GetBuffer(MAX_PATH));
FillOneItem(OneExe,j);
}
}
////
BOOL CPropPage4::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: Add extra initialization here
FillOpenWithList();
UpdateData(FALSE); return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}void CPropPage4::OnPropp4Other()
{
// TODO: Add your control notification handler code here
AfxMessageBox(IDS_APP_NOT_IMPL);
}void CPropPage4::OnCancel()
{
// TODO: Add your specialized code here and/or call the base class
CPropertyPage::OnCancel();
}void CPropPage4::OnOK()
{
// TODO: Add your specialized code here and/or call the base class
int selectNo=m_P4ListCtrl.GetSelectedCount();
int nItem=-1;
POSITION pos = m_P4ListCtrl.GetFirstSelectedItemPosition();
while (pos)
{
nItem = m_P4ListCtrl.GetNextSelectedItem(pos);
}
if(nItem>=0)
{
int count=m_CommandArray.GetSize();
// for (int j=0;j<count;j++)
{
m_ExeFullName=m_CommandArray[0];
//AfxMessageBox(m_ExeName);
}
LVITEM lvi;
lvi.mask=LVIF_PARAM;
lvi.iItem=nItem;
lvi.iSubItem=0;
m_P4ListCtrl.GetItem(&lvi);
m_ExeFullName=m_CommandArray[lvi.lParam];// full path
} CPropertyPage::OnOK();
}