|
如有代码,另加200分! |
|
|
|
void __fastcall TfrmMain::sbnLoadExeClick(TObject *Sender)
{ SHELLEXECUTEINFO ExeInfo; ZeroMemory ( &ExeInfo, sizeof( SHELLEXECUTEINFO) ); ExeInfo.cbSize = sizeof( SHELLEXECUTEINFO ); ExeInfo.lpDirectory = (LPSTR)lpDirectory; ExeInfo.lpParameters = (LPSTR)lpParameters; ExeInfo.fMask = SEE_MASK_NOCLOSEPROCESS ; ExeInfo.nShow = SW_MAXIMIZE;//SW_HIDE; try { ShellExecuteEx ( &ExeInfo ); this->Hide(); } catch (Exception &exception) { Application->ShowException(&exception); this->Show(); } for ( ; ; ) // 等待外部程序结束 { Application->ProcessMessages(); if ( WAIT_TIMEOUT != WaitForSingleObject ( ExeInfo.hProcess, 550 ) ) break; } this->Show(); this->SetFocus(); this->BringToFront(); } |
|
|
#include <Shellapi.h>
void __fastcall TForm1::sbnLoadExeClick(TObject *Sender) { SHELLEXECUTEINFO ExeInfo; ZeroMemory ( &ExeInfo, sizeof( SHELLEXECUTEINFO) ); ExeInfo.cbSize = sizeof( SHELLEXECUTEINFO ); ExeInfo.lpFile = "notepad.exe"; ExeInfo.lpDirectory = "";//(LPSTR)lpDirectory; ExeInfo.lpParameters = "D:\\1.txt";//(LPSTR)lpParameters; ExeInfo.fMask = SEE_MASK_NOCLOSEPROCESS ; ExeInfo.nShow = SW_MAXIMIZE;//SW_HIDE; try { ShellExecuteEx ( &ExeInfo ); // this->Hide(); } catch (Exception &exception) { Application->ShowException(&exception); // this->Show(); } for ( ; ; ) // 等待外部程序结束 { Application->ProcessMessages(); if ( WAIT_TIMEOUT != WaitForSingleObject ( ExeInfo.hProcess, 550 ) ) break; } // this->Show(); this->SetFocus(); this->BringToFront(); } |
|
|
迟到一步,比我的强
|
|
|
不错
来接分! |
|
|
能不能用进程调用临界资源的方法?
当乙文件退出时,设置标记为不可用。 然后让甲退出。 |
|
|
谢谢Behard(我爱天安门) 。
我忘了说了,具体的文件类型未知,用它的关联文件打开,比如.txt文件用notepad.exe打开灰,.doc文件用word.exe打开,.htm文件用iexplorer打开,等等。 |
|
|
TO:manyroads(流水……小飞侠)
有没有具体的代码例子呢? |
|
|
用spawnl调用,具体使用查查联机帮助
P_WAIT参数用来等待外部程序执行结束 fname为文件名 绝对可行 AnsiString pgm = "notepad.exe"; int retn = spawnl(P_WAIT, pgm.c_str(), pgm.c_str(), fname.c_str() ,NULL); |
|
|
TO:luomh98(luomh98)
这方法可能不行,因为不知文件的具体类型,所以,不能确认打开它的就是notepad.exe,还是word.exe,或是别的程序。 |
|
|
用写在注册表中的文件关联信息
|
|
|
那就直接运行这个文件。在 Behard(我爱天安门) 代码的基础上修改一下:
void __fastcall TForm1::Button1Click(TObject *Sender) { String strFileName; TOpenDialog *p=new TOpenDialog(Form1); p->Filter="*.*|*.*"; if(p->Execute()) strFileName=p->FileName; delete p; if(strFileName=="") return; SHELLEXECUTEINFO ExeInfo; ZeroMemory ( &ExeInfo, sizeof( SHELLEXECUTEINFO) ); ExeInfo.cbSize = sizeof( SHELLEXECUTEINFO ); ExeInfo.lpFile = strFileName.c_str(); ExeInfo.lpDirectory = "";//(LPSTR)lpDirectory; //ExeInfo.lpParameters = "D:\\1.txt";//(LPSTR)lpParameters; ExeInfo.fMask = SEE_MASK_NOCLOSEPROCESS ; ExeInfo.nShow = SW_MAXIMIZE;//SW_HIDE; try { ShellExecuteEx ( &ExeInfo ); // this->Hide(); } catch (Exception &exception) { Application->ShowException(&exception); // this->Show(); } for ( ; ; ) // 等待外部程序结束 { Application->ProcessMessages(); if ( WAIT_TIMEOUT != WaitForSingleObject ( ExeInfo.hProcess, 550 ) ) break; } // this->Show(); this->SetFocus(); this->BringToFront(); } |
|
|
学习
接分 |
|
|
学习
|
|
|
TO: Behard(我爱天安门)和ccrun(老妖)(www.ccrun.com)
你们的方法不错!但还有个问题,比如,本来已经打开了word程序,再通过甲程序调用word打开.doc文件,那么,执行这段时就有问题了: for ( ; ; ) // 等待外部程序结束 { Application->ProcessMessages(); if ( WAIT_TIMEOUT != WaitForSingleObject ( ExeInfo.hProcess, 550 ) ) break; } 就是说,程序根本就不等别人,一启动自己就结束了,有没更好的办法解决这个问题呢? |
|
|
学习!!!!
|
|
|
又学一招!
|
|
|
GetExitCodeProcess(piProcInfo.hProcess,ExitCode);
|
|
|
一些软件开发环境中的实现好像是这样的:
在界面没有失去焦点时,不管打开的文件是否被改变;在界面失去焦点后,还是不处理,在界面重新获得焦点时,才检查文件是否备更新了。 如果一直要检查,可否使用定时器? 检查文件是否被更新,可以使用文件的最后修改时间。 |
|
|
学习
|
|
|
“你们的方法不错!但还有个问题,比如,本来已经打开了word程序,再通过甲程序调用word打开.doc文件,那么,执行这段时就有问题了:
for ( ; ; ) // 等待外部程序结束 { Application->ProcessMessages(); if ( WAIT_TIMEOUT != WaitForSingleObject ( ExeInfo.hProcess, 550 ) ) break; } 就是说,程序根本就不等别人,一启动自己就结束了,有没更好的办法解决这个问题呢?“ 我猜测是Word这个进程打开失败了(因为已经运行了一个word,则使用原来的Word打开,因此。 |
|
|
不是失败,而是关闭了,
|
|
|
把这段程序修改一下,查找winword是否已经在运行。如果在运行,找到它的Process handle,word本身会保证只运行一个Word。
不过这样又不能做到子窗口关闭的监测,也可以试试或的那个word子窗口的线程,用线程内河对象来判断。 妈的,这边没BCB,郁闷。。 |
|
To jiangchun_xn(【GrayMemory】) :
这个东西使用 VC 做还是一样的 |
|
我现在在公司,没有时间测试
晚上看有没有时间再说吧 |
|
能不能创建一个新的进程,进入调试模式,然后。。。后面我也不知道。
|
|
?
|
|
VC,呵呵,更没有了。。。
|
|
在程序运行前,先检测是否有word窗口,如有,給出提示先进行关闭。
|
|
测试了一下,好像使用 CreateProcess 还是同样的问题
void __fastcall TForm1::Button9Click(TObject *Sender) { STARTUPINFO si; PROCESS_INFORMATION pi; memset ( &si, 0, sizeof(si) ); si.cb = sizeof ( STARTUPINFO ); CreateProcess("C:\\Program Files\\Microsoft Office\\Office\\WINWORD.EXE", "Open D:\\1.doc", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); for ( ; ; ) { Application->ProcessMessages(); if ( WAIT_TIMEOUT != WaitForSingleObject(pi.hProcess, 100 ) ) break; } ShowMessage ( "OK!" ); } 不过我查看了一下 WORD 的窗口,GetWindowText 为 "文件名 - Microsoft Word" GetClassName 为 OpusApp |
|
Word打开一个文档前,就自己监测是否几经有word,有的话就通知那个word打开这个文件,当前进程结束,就是Behard(我爱天安门) 中马上就出来OK的原因,这里面hProcess就结束了。
|
|
学习
|
|
学习。
|
|
TO:pms(高山流水) 和 Behard(我爱天安门)
如何检测是否有word窗口(或其他应用程序窗口,如iexplorer窗口)?能否给出源代码?谢谢! |
|
这个没有办法得,因为它是用自窗口的办法,除非有办法拦截到那个子窗口关闭的消息,但是这样比较麻烦。找到word的代码:(delphi)的,自己翻译
var FSnapshotHandle:THandle; FProcessEntry32:TProcessEntry32; Ret : BOOL; ProcessID : integer; ProcessHndle : THandle; lpBuffer:pByte; nSize: DWORD; lpNumberOfBytesRead: DWORD; i:integer; s:string; begin FSnapshotHandle:=CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS,0); //创建系统快照 FProcessEntry32.dwSize:=Sizeof(FProcessEntry32); //先初始化 FProcessEntry32 的大小 Ret:=Process32First(FSnapshotHandle,FProcessEntry32); while Ret do begin s:=ExtractFileName(FProcessEntry32.szExeFile); if s='KERNEL32.DLL' then begin ProcessID:=FProcessEntry32.th32ProcessID; s:=''; break; end; FProcessEntry32.th32ProcessID,8)); ProcessHndle:=OpenProcess(PROCESS_VM_READ,false,ProcessID); if(FProcessEntry32.szExeFile='winWord.exe') then { ................................. } Ret:=Process32Next(FSnapshotHandle,FProcessEntry32); end; //循环枚举出系统开启的所有进程,找出“Kernel32.dll” CloseHandle(FSnapshotHandle); |
|
include <vcl.h>
#pragma hdrstop #include "Unit1.h" //甲窗体的头函数 用File->Include Unit Hdr Alt+F11 菜单项将窗体甲的头函数包含进来。 #include "Unit2.h" //乙窗体的头函数 //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form2; / void __fastcall TForm2::FormDblClick(TObject *Sender) { int i=MessageDlg("asd",mtInformation,TMsgDlgButtons()<<mbOK<<mbCancel,0); Caption=i; if (i==1) { //甲乙窗体都关闭 Form1->Close(); Form2->Close(); } else{ //只关闭乙窗体 Form1->Close(); } } 你是否是这个意思,请执行这些代码 |
|
上面的代码有小错误,按这个纠正一下:
include <vcl.h> #pragma hdrstop #include "Unit1.h" //甲窗体的头函数 用File->Include Unit Hdr Alt+F11 菜单项将窗体甲的头函数包含进来。 #include "Unit2.h" //乙窗体的头函数 //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form2; / void __fastcall TForm2::FormDblClick(TObject *Sender) { int i=MessageDlg("asd",mtInformation,TMsgDlgButtons()<<mbOK<<mbCancel,0); Caption=i; if (i==1) { //甲乙窗体都关闭 Form1->Close(); Form2->Close(); } else{ //只关闭乙窗体 Form2->Close(); //这是修改后的错误行 } } 你是否是这个意思,请执行这些代码 |
|
up
|
|
up
|
|
TO: Bkoklam(koklam)
我说的意思不是那个啊。 |
|
struct WINLIST
{ HANDLE hWnd; char cWinBuf[256]; }; struct WINLIST gWinList[256]; int giCountWin; bool CALLBACK EnumWindowsProc( HWND hWnd, LPARAM lParam ) { char buffer[256]; GetWindowText(hWnd, buffer, 256); if ( strlen(buffer) ) { if (giCountWin < 256) { gWinList[ giCountWin].hWnd = hWnd; //strcpy(gWinList[giCountWin].cWinBuf,buffer); sprintf(gWinList[giCountWin].cWinBuf,"%s,\t0x%08x",buffer,hWnd ) ; giCountWin ++; } } return true; } void __fastcall TForm1::Button1Click(TObject *Sender) { giCountWin = 0; EnumWindows( (WNDENUMPROC)EnumWindowsProc,0); for ( j = 0; j<giCountWin; j++) { if ( strcmp(gWinList[j].cWinBuf,"Default IME") != 0 ) Form1->ListBox1->Items->Add(gWinList[j].cWinBuf); } } |
|
void __fastcall TForm1::Button1Click(TObject *Sender)
{ giCountWin = 0; EnumWindows( (WNDENUMPROC)EnumWindowsProc,0); for ( j = 0; j<giCountWin; j++) { if ( strstr(gWinList[j].cWinBuf,"Default IME") == NULL ) Form1->ListBox1->Items->Add(gWinList[j].cWinBuf); } } |
|
不错!
|
|
to:puma66()
没有,这个学期学操作系统,所以有此想法。 上课没学到代码。不好意思 |
|
WORD只允许存在一个实例,如果新的实例启动后发现有正在运行的实例,就是马上退出,所以你第二次的等待会立刻结束。
而如果使用notepad就不会出现这种情况。 另外还要注意 Behard(我爱天安门) 的代码会引起递归调用的。 因为ProcessMessage()会间接的再次调用事件句柄的,如果你用notepad进行试验会发现一旦再次运行notepad时,第一次的while循环就不会退出了。实际上由于处理消息的只有主线程,所以任何等待都会在主线程中。 建议你在新开启一个实例时,新启用一个线程进行等待,如果等待完成后再向主线程发送一个消息就可以了。 |
|
谢谢Behard(我爱天安门) 等朋友!
这几天电脑出问题,待我试完以上代码后再结贴。 |
|
最近太忙,先结贴再说。
另外再加的200分,我以后肯定会兑现的! |