Подскажите плиз, почему программа не выходит из цикла Код (Text): repeat Reason:= MsgWaitForMultipleObjects(1, Event, FALSE, INFINITE, QS_ALLEVENTS); if Reason = WAIT_OBJECT_0 + 1 then ProcessMessage; until Reason = WAIT_OBJECT_0; если хоть раз произойдет событие WM_DEVICECHANGE?? Если же событие не происходит,прога из цикла выходит нормально. Код (Text): program Loader; uses Windows, Messages; const WindowClassName: PChar = 'LoaderWindow'; WM_DEVICECHANGE = $0219; DBT_DEVICEARRIVAL = $8000; DBT_DEVTYP_VOLUME = $00000002; WM_SENDMESSAGE = WM_USER + $0001; type PDevBroadcastHdr = ^TDevBroadcastHdr; DEV_BROADCAST_HDR = packed record dbch_size: DWORD; dbch_devicetype: DWORD; dbch_reserved: DWORD; end; TDevBroadcastHdr = DEV_BROADCAST_HDR; type PDevBroadcastVolume = ^TDevBroadcastVolume; DEV_BROADCAST_VOLUME = packed record dbcv_size: DWORD; dbcv_devicetype: DWORD; dbcv_reserved: DWORD; dbcv_unitmask: DWORD; dbcv_flags: Word; end; TDevBroadcastVolume = DEV_BROADCAST_VOLUME; var WindowHandle: THandle; procedure SendKillSignal; var WindowHandle: THandle; begin WindowHandle:= FindWindow('MusicMegaBox_Window', nil); if WindowHandle = 0 then MessageBox(0,'Not found','',0) else Sendmessage(WindowHandle, WM_SENDMESSAGE, 1 ,0); end; // Маска имени диска. Возвращаемое значение состоит из битов, // соответствующих именам дисков: // бит 0=A, бит 1=B, бит 3=C и т.д. function GetDiskName(unitmask : Longint) : string; var i : Integer; begin For i:= 0 to 26 do begin if ((unitmask and 1) <> 0) then Break; unitmask:= unitmask shr 1; End; Result:= Char(Integer('A')+i); end; function WndProc(WindowHandle: THandle; Message: DWord; WParam: Integer; LParam: Integer): Integer; stdcall; var LPDB: PDevBroadcastHdr; LPDBV: PDevBroadcastVolume; begin case Message of WM_DEVICECHANGE: begin if WParam = DBT_DEVICEARRIVAL then //Добавление нового устройства begin LPDB:= PDevBroadcastHdr(LParam); if LPDB^.dbch_devicetype = DBT_DEVTYP_VOLUME then begin LPDBV:= PDevBroadcastVolume(LParam); // MessageBox(0, PChar('>>Добавлен логический диск. Имя: '+GetDiskName(lpdbv.dbcv_unitmask)),'Hi', 0); SendKillSignal; end; end; Result:= 0; end; else Result := DefWindowProc(WindowHandle, Message, WParam, LParam); end; end; function CreateWindow: Boolean; var WindowClass: TWndClass; begin ZeroMemory(@WindowClass, SizeOf(WindowClass)); WindowClass.lpfnWndProc:= @WndProc; WindowClass.lpszClassName:= WindowClassName; if RegisterClass(WindowClass) <> 0 then begin WindowHandle:= CreateWindowEx(0, WindowClassName, nil, WS_OVERLAPPED, 0, 0, 0, 0, 0, 0, 0, nil); UpdateWindow(WindowHandle); if WindowHandle <> 0 then Result:= True else Result:= False; end else Result:= False; end; procedure ProcessMessage; var Msg: TMsg; begin while GetMessage(Msg, 0, 0, 0) do begin TranslateMessage(msg); DispatchMessage(msg); end; end; function RunAndMsgWait(_Application: String): Boolean; var SI: TStartupInfo; PI: TProcessInformation; Event: THandle; Reason: DWord; begin FillChar(SI, SizeOf(SI), 0); SI.cb:= SizeOf(SI); FillChar(PI, SizeOf(PI), 0); if CreateProcess(nil, PChar(_Application), nil, nil, false, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, SI, PI) then begin Event:= PI.hProcess; repeat Reason:= MsgWaitForMultipleObjects(1, Event, FALSE, INFINITE, QS_ALLEVENTS); if Reason = WAIT_OBJECT_0 + 1 then ProcessMessage; until Reason = WAIT_OBJECT_0; CloseHandle(PI.hProcess); CloseHandle(PI.hThread); Result:= True; end else Result:= False; end; begin if CreateWindow then // RunAndMsgWait('C:\MusicMegaBox\MusicMegaBox.EXE'); RunAndMsgWait('cmd.exe'); end.
spider13 А разве второй параметр MsgWaitForMultipleObjects не должен быть указателем на массив хэндлов, а не самим хэндлом?
spider13 Еще как важно. Передавать указатель на хэндл процесса нужно, а не сам хэндл. Независимо от того, сколько там всего хэндлов.
n0name +1. К тому же если объект один, то зачем использовать MultipleObjects. Чем не нравится Single object?
Народ, а это точно форум wasm.ru???? я случайно не ошибся? Я думал что на этом форуме одни профи, даже вопросы сюда пише оч редко, зачем людей тривожить по пустякам)))) 1) функция MsgWaitForMultipleObjects описываеться так. Код (Text): function MsgWaitForMultipleObjects(nCount: DWORD; var pHandles; fWaitAll: BOOL; dwMilliseconds, dwWakeMask: DWORD): DWORD; stdcall; отсюда видно, что сохраняеться сразу указатель на переменную, а не сама переменная. 2)я никого не игнорю, я говорю что проблема не в этом, а здесь все работает правильно. 3) функция WaitForSingleObject не поможет, так как мне необходимо еще и обрабатывать сообщения.
max7C4 Вообще MsgWaitForMultipleObjects позволяет ожидать также и события ввода, что здесь и используется. spider13 А у Вас помимо неверного второго параметра происходит зацикливание в ProcessMessage на функции GetMessage вплоть до получения сообщения WM_QUIT. Используйте PeekMessage вместо GetMessage, т.к. GetMessage блокирует работу потока до получения следующего сообщения. P.S. Так бы сразу и сказали.