Прога не выходит из цикла.

Тема в разделе "WASM.BEGINNERS", создана пользователем spider13, 22 июн 2008.

  1. spider13

    spider13 New Member

    Публикаций:
    0
    Регистрация:
    9 апр 2007
    Сообщения:
    20
    Подскажите плиз, почему программа не выходит из цикла

    Код (Text):
    1.    repeat
    2.       Reason:= MsgWaitForMultipleObjects(1, Event, FALSE, INFINITE, QS_ALLEVENTS);
    3.       if Reason = WAIT_OBJECT_0 + 1 then
    4.         ProcessMessage;
    5.     until Reason = WAIT_OBJECT_0;
    если хоть раз произойдет событие WM_DEVICECHANGE?? Если же событие не происходит,прога из цикла выходит нормально.

    Код (Text):
    1. program Loader;
    2.  
    3. uses
    4.   Windows, Messages;
    5.  
    6. const
    7.   WindowClassName: PChar = 'LoaderWindow';
    8.   WM_DEVICECHANGE = $0219;
    9.   DBT_DEVICEARRIVAL = $8000;
    10.   DBT_DEVTYP_VOLUME = $00000002;
    11.   WM_SENDMESSAGE = WM_USER + $0001;
    12.  
    13. type
    14.   PDevBroadcastHdr = ^TDevBroadcastHdr;
    15.   DEV_BROADCAST_HDR = packed record
    16.     dbch_size: DWORD;
    17.     dbch_devicetype: DWORD;
    18.     dbch_reserved: DWORD;
    19.   end;
    20.   TDevBroadcastHdr = DEV_BROADCAST_HDR;
    21.  
    22. type
    23.   PDevBroadcastVolume = ^TDevBroadcastVolume;
    24.   DEV_BROADCAST_VOLUME = packed record
    25.     dbcv_size: DWORD;
    26.     dbcv_devicetype: DWORD;
    27.     dbcv_reserved: DWORD;
    28.     dbcv_unitmask: DWORD;
    29.     dbcv_flags: Word;
    30.   end;
    31.   TDevBroadcastVolume = DEV_BROADCAST_VOLUME;
    32.  
    33. var
    34.   WindowHandle: THandle;
    35.  
    36. procedure SendKillSignal;
    37. var
    38.   WindowHandle: THandle;
    39. begin
    40.   WindowHandle:= FindWindow('MusicMegaBox_Window', nil);
    41.   if WindowHandle = 0 then
    42.    MessageBox(0,'Not found','',0)
    43.   else
    44.    Sendmessage(WindowHandle, WM_SENDMESSAGE, 1 ,0);
    45. end;
    46.  
    47. // Маска имени диска. Возвращаемое значение состоит из битов,
    48. // соответствующих именам дисков:
    49. // бит 0=A, бит 1=B, бит 3=C и т.д.
    50. function GetDiskName(unitmask : Longint) : string;
    51. var i : Integer;
    52. begin
    53.  For i:= 0 to 26 do begin
    54.   if ((unitmask and 1) <> 0) then Break;
    55.   unitmask:= unitmask shr 1;
    56.  End;
    57.  Result:= Char(Integer('A')+i);
    58. end;
    59.  
    60. function WndProc(WindowHandle: THandle; Message: DWord; WParam: Integer; LParam: Integer): Integer; stdcall;
    61. var
    62.   LPDB: PDevBroadcastHdr;
    63.   LPDBV: PDevBroadcastVolume;
    64. begin
    65.   case Message of
    66.     WM_DEVICECHANGE: begin
    67.                        if WParam = DBT_DEVICEARRIVAL then //Добавление нового устройства
    68.                        begin
    69.                          LPDB:= PDevBroadcastHdr(LParam);
    70.                          if LPDB^.dbch_devicetype = DBT_DEVTYP_VOLUME then
    71.                          begin
    72.                            LPDBV:= PDevBroadcastVolume(LParam);
    73. //                           MessageBox(0, PChar('>>Добавлен логический диск. Имя: '+GetDiskName(lpdbv.dbcv_unitmask)),'Hi', 0);
    74.                            SendKillSignal;
    75.                          end;
    76.                        end;
    77.                        Result:= 0;
    78.                      end;
    79.   else
    80.     Result := DefWindowProc(WindowHandle, Message, WParam, LParam);
    81.   end;
    82. end;
    83.  
    84. function CreateWindow: Boolean;
    85. var
    86.   WindowClass: TWndClass;
    87. begin
    88.   ZeroMemory(@WindowClass, SizeOf(WindowClass));
    89.   WindowClass.lpfnWndProc:= @WndProc;
    90.   WindowClass.lpszClassName:= WindowClassName;
    91.   if RegisterClass(WindowClass) <> 0 then
    92.   begin
    93.     WindowHandle:= CreateWindowEx(0, WindowClassName, nil, WS_OVERLAPPED, 0, 0, 0, 0, 0, 0, 0, nil);
    94.     UpdateWindow(WindowHandle);
    95.     if WindowHandle <> 0 then
    96.       Result:= True
    97.     else
    98.       Result:= False;
    99.   end
    100.   else
    101.     Result:= False;
    102. end;
    103.  
    104. procedure ProcessMessage;
    105. var
    106.   Msg: TMsg;
    107. begin
    108.   while GetMessage(Msg, 0, 0, 0) do
    109.   begin
    110.     TranslateMessage(msg);
    111.     DispatchMessage(msg);
    112.   end;
    113. end;
    114.  
    115. function RunAndMsgWait(_Application: String): Boolean;
    116. var
    117.   SI: TStartupInfo;
    118.   PI: TProcessInformation;
    119.   Event: THandle;
    120.   Reason: DWord;
    121. begin
    122.   FillChar(SI, SizeOf(SI), 0);
    123.   SI.cb:= SizeOf(SI);
    124.   FillChar(PI, SizeOf(PI), 0);
    125.   if CreateProcess(nil, PChar(_Application), nil, nil, false, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, SI, PI) then
    126.   begin
    127.     Event:= PI.hProcess;
    128.     repeat
    129.       Reason:= MsgWaitForMultipleObjects(1, Event, FALSE, INFINITE, QS_ALLEVENTS);
    130.       if Reason = WAIT_OBJECT_0 + 1 then
    131.         ProcessMessage;
    132.     until Reason = WAIT_OBJECT_0;
    133.     CloseHandle(PI.hProcess);
    134.     CloseHandle(PI.hThread);
    135.     Result:= True;
    136.   end
    137.   else
    138.     Result:= False;
    139. end;
    140.  
    141. begin
    142.   if CreateWindow then
    143. //    RunAndMsgWait('C:\MusicMegaBox\MusicMegaBox.EXE');
    144.     RunAndMsgWait('cmd.exe');
    145. end.
     
  2. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    spider13
    А разве второй параметр MsgWaitForMultipleObjects не должен быть указателем на массив хэндлов, а не самим хэндлом?
     
  3. spider13

    spider13 New Member

    Публикаций:
    0
    Регистрация:
    9 апр 2007
    Сообщения:
    20
    Да там по сути неважно, параметр же один!
    Проблема точно не в этом!
     
  4. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    spider13
    Еще как важно. Передавать указатель на хэндл процесса нужно, а не сам хэндл. Независимо от того, сколько там всего хэндлов.
     
  5. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    дык если сам знаешь в чем проблема смысл создавать тему?
    тебе указывают на ошибку, а ты игноришь...
     
  6. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    n0name
    +1. К тому же если объект один, то зачем использовать MultipleObjects. Чем не нравится Single object?
     
  7. spider13

    spider13 New Member

    Публикаций:
    0
    Регистрация:
    9 апр 2007
    Сообщения:
    20
    Народ, а это точно форум wasm.ru????
    я случайно не ошибся? Я думал что на этом форуме одни профи, даже вопросы сюда пише оч редко, зачем людей тривожить по пустякам))))

    1) функция MsgWaitForMultipleObjects описываеться так.

    Код (Text):
    1. function MsgWaitForMultipleObjects(nCount: DWORD; var pHandles;
    2.   fWaitAll: BOOL; dwMilliseconds, dwWakeMask: DWORD): DWORD; stdcall;
    отсюда видно, что сохраняеться сразу указатель на переменную, а не сама переменная.

    2)я никого не игнорю, я говорю что проблема не в этом, а здесь все работает правильно.
    3) функция WaitForSingleObject не поможет, так как мне необходимо еще и обрабатывать сообщения.
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    max7C4
    Вообще MsgWaitForMultipleObjects позволяет ожидать также и события ввода, что здесь и используется.
    spider13
    А у Вас помимо неверного второго параметра происходит зацикливание в ProcessMessage на функции GetMessage вплоть до получения сообщения WM_QUIT. Используйте PeekMessage вместо GetMessage, т.к. GetMessage блокирует работу потока до получения следующего сообщения.
    P.S.
    Так бы сразу и сказали. :)
     
  9. spider13

    spider13 New Member

    Публикаций:
    0
    Регистрация:
    9 апр 2007
    Сообщения:
    20
    l_inc, огромное спасибо, помогло))
    Сорри, за грубость...