Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > ожидание потока или хз чего это


Автор: Cashey 15.5.2008, 16:04
в общем задача такая. происходит некоторое событие и должен активироватся поток с мониторингом печати, и накапливать информацию о посылке печати на принтер. на эту тему посты на форуме уже не раз поднимались, но вразумительного ответа ни один из них не получил.

и так, что делаю я:
Код

procedure TPrintSpooler.Execute;
var
  lNext: LongBool;
{******************************************}
{Эти структуры мне не нужны, но для параметра в FindNextPrinterChangeNotification пришлось их создать}
  pdwChange: DWORD;
  PrintOptions: PRINTER_NOTIFY_OPTIONS; 

  pPrnNotifyInfo: pPrinterNotifyInfo;
  PrnNotifyInfo: PRINTER_NOTIFY_INFO;

  pPrnNotifyInfoData: pPrinterNotifyInfoData;
  PrnNotifyInfoData: PRINTER_NOTIFY_INFO_DATA;
{*******************************************}
begin
  hPrinter := OpenCurrentPrinterHandle;
  hNotification := FindFirstPrinterChangeNotification(hPrinter,PRINTER_CHANGE_ALL,0,nil);      //PRINTER_CHANGE_JOB
  if hNotification = INVALID_HANDLE_VALUE then begin
    ErrorCode := GetLastError ;
    Synchronize(MainForm.showerror);
    ClosePrinter(hPrinter);
  end;
repeat
Synchronize(MainForm.EnabledF);   //это для визуального контроля работы процесса
  lNext := false;
  hWait := WaitForSingleObject(hNotification, INFINITE);
  case hWait of
   WAIT_FAILED : ErrorCode := GetLastError ;
   WAIT_OBJECT_0 : lNext := FindNextPrinterChangeNotification(hNotification,
   pdwChange, @PrintOptions, Pointer(pPrnNotifyInfo));
   else
     Synchronize(MainForm.showerror1);
   end;

  if lNext then 
    MainForm.UpdatePrinter(hPrinter);  // здесь вызывается EnumJobs
    sleep(100);
    Synchronize(MainForm.EnabledT);   //это для визуального контроля работы процесса
 until Terminated;
    FindClosePrinterChangeNotification(hNotification);
    CloseHandle(hNotification);
    CloseHandle(hPrinter);
end;

{Открываем принтер и получаем его хендл}
function OpenCurrentPrinterHandle: THandle;
var
  Device, Driver, Port: array[0..255] of Char;
  hDeviceMode: THandle;
begin
  Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
  if not OpenPrinter(@Device, Result, nil) then
    RaiseLastWin32Error;
end;


что происходит: при запуске процесса первые 15-20 сек. он чем то занят, потом отрабатывается if lNext then, причем никакой работы с принтером в этот момент нет. затем цикл крутит и lNext всегда false даже если принтер печатает. Кто-нить работал с ожиданиями?

Автор: dumb 15.5.2008, 16:19
если lNext false, неплохо GetLastError посмотреть.

со спецификой мониторинга принтера не знаком, посему вот тебе первый "напаренный" http://cc.codegear.com/Item.aspx?id=20307 smile

Автор: Cashey 16.5.2008, 16:24
Цитата(dumb @  15.5.2008,  17:19 Найти цитируемый пост)
если lNext false, неплохо GetLastError посмотреть.

да, действительно, выдается ощибка 87 , что расшифровывается как "Параметр задан неверно"

изменил код таким образом
Код

  if lNext then
    MainForm.UpdatePrinter(hPrinter)
  else begin
    ErrorCode := GetLastError;
    Synchronize(MainForm.showerror);
  end;

а в showerror прописал
Код
procedure TMainForm.showerror;
var
 MsgBuf: PChar;
begin
 if FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER or
     FORMAT_MESSAGE_FROM_SYSTEM,
     nil,
     unit3.ErrorCode,
     0,
     @MsgBuf,
     0,
     nil) > 0 then
     begin
      ShowMessage('Ошибка : ' + MsgBuf);
      LocalFree(Cardinal(MsgBuf));
     end
end;


видимо при повторном вызове надо изменить параметры FindNextPrinterChangeNotification, но вот только на что?

Автор: dumb 16.5.2008, 16:59
тонкостей дельфевого синтаксиса не помню, посему предположение такое: pdwChange - это таки адрес(хотя @ оно(дельфо) вроде само догадывается брать в зависимости от сигнатуры вызываемой функции), ну и неинициализированная структура PrintOptions.

Код

dwChange: DWORD;
...
FindNextPrinterChangeNotification(hNotification, @dwChange, nil, Pointer(pPrnNotifyInfo));
?

Автор: Cashey 16.5.2008, 20:06
Цитата(dumb @  16.5.2008,  17:59 Найти цитируемый пост)
FindNextPrinterChangeNotification(hNotification, @dwChange, nil, Pointer(pPrnNotifyInfo));

пробовал. тогда выдается ошибка "Неверный дескриптор"

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)