Советы по Delphi. Версия 1.4.3 от 1.1.2001 - страница 12
>
И все. Точность этого способа до 1 мсек. минимальный интервал времени можно задавать 1 мсек.
Обратите внимание на то, что все CALLBACK-функции, вызываемые Windows, должны использовать соглашение о вызовах stdcall.
Как сделать чтобы при событиях моя программа отпpавляла кому-либо сообщение на мой компьютеp?
Nomadic рекомендует следующий код:
Если только послать, то проще всего, пожалуй…
W32: F1 «NetMessageBufferSend»;
Win16: Почему-то не описан, но руками наковырял…
>function NetMessageBufferSend(Zero1, Zero2: Word; WhoTo: PChar; Buffer: PChar; BufSize: Word): Integer; external 'netapi' index 525;
«Кому» может быть '*' == всем.
Что нужно давать WSAAsyncSelect в качестве параметра handle, если тот запускается и используется в dll (init), и никакой формы (у которой можно было бы взять этот handle) в этой dll не создается?
Nomadic рекомендует следующий код:
>const WM_ASYNCSELECT = WM_USER+0;
>type TNetConnectionsManager = class(tobject)
>protected
> FWndHandle : HWND;
>procedure WndProc(var MsgRec : TMessage);
> …
>end;
>constructor TNetConnectionsManager.Create
>begin
> inherited Create;
> FWndHandle := AllocateHWnd(WndProc);
> …
>end;
>destructor TNetConnectionsManager.Destroy;
>begin
> …
> if FWndHandle<>0 then DeallocateHWnd(FWndHandle);
> inherited Destroy;
>end;
>procedure TNetConnectionsManeger.WndProc(var MsgRec : TMessage);
>begin
> with MsgRec do
> if Msg = WM_ASYNCSELECT then WMAsyncSelect(MsgRec)
> else DefWindowProc(FWndHandle, Msg, wParam, lParam);
>end;
Hо pекомендую посмотpеть WinSock2, в котоpом можно:
>WSAEventSelect(FSocket, FEventHandle, FD_READ or fd_close);
>WSAWaitForMultipleEvents(…);
>WSAEnumNetworkEvents(FSocket, FEventHandle, lpNetWorkEvents);
То есть, обойтись без окон и без очеpеди сообщений windows, а заодно иметь возможность pаботать и с IPX/SPX, и с netbios.
Вызов других программ
VRSLazy@mail.ru пишет:
Доброго времени суток,
Вот посмотрел Ваше произведение Советы по делфи, мне очень понравилось :-)
Правда в вопросе/решении запустить другую программу просто обалдел :-( Я как то долго мучился с этим самым ShellExecute пока не пришёл к следующему:
>uses …ToolWin, Windows …
>procedure Run(App: String);
>var
> ErrStr : String;
> PMSI: TStartupInfo;
>PMPI: TProcessInformation;
>begin
> try
> CreateProcess(nil, @App[1] , nil, nil, False, NORMAL_PRIORITY_CLASS, nil, nil, PMSI, PMPI);
> except
> ErrStr := 'Fault run process: '''+App+'''';
> Application.MessageBox(@ErrStr[1],'Failure process', MB_OK+MB_ICONERROR);
>end;
разумеется это одно из самых корявых решений, но всё же работает, как вариант сойдет?
Получение списка запущеных приложений
Igor Nikolaev aKa The Sprite предлагает следующий код:
>procedure TForm1.Button1Click(Sender: TObject);
>VAR
> Wnd : hWnd;
> buff: ARRAY [0..127] OF Char;
>begin
> ListBox1.Clear;
> Wnd := GetWindow(Handle, gw_HWndFirst);
> WHILE Wnd <> 0 DO BEGIN {Hе показываем:}
> IF (Wnd <> Application.Handle) AND {-Собственное окно}
> IsWindowVisible(Wnd) AND {-Hевидимые окна}
> (GetWindow(Wnd, gw_Owner) = 0) AND {-Дочернии окна}
> (GetWindowText(Wnd, buff, sizeof(buff)) <> 0)
> THEN BEGIN
> GetWindowText(Wnd, buff, sizeof(buff));
> ListBox1.Items.Add(StrPas(buff));
> END;
> Wnd := GetWindow(Wnd, gw_hWndNext);
> END;
> ListBox1.ItemIndex := 0;
>end;
Как мне запустить какую-нибудь программу? А как подождать, пока эта программа не отработает? Как выяснить, работает ли программа или уже завершилась? Как принудительно закрыть выполняющуюся программу?
Nomadic рекомендует следующее:
A: WinExec() или ShellExecute. У второй больше возможностей.
(SO): CreateProcess() в параметре process info возвращает handle запущенного процесса. Вот и делаешь WaitForSingleObject(pi.hProcess, INFINITE);
(AA): (Win16) Delay можно взять из rxLib.
>handle := WinExec(…);
>if handle >= 32 then
>while GetModuleUsage(handle) > 0 do Delay(nn);
>else raise …
(AM): Чтобы выяснить, работает ли программа, используйте GetProcessTimes(), параметр lpExitTime.
(Win32) Для принудительного завершения процесса — TerminateProcess.
(Win16) (RR): Надо послать программе сообщение WM_QUIT:
>Handle := Winexec(App, 0);
>PostMessage(Handle, WM_QUIT, 0, 0);
Открытие выбранного файла в работающем приложении