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


Автор: BpIstorick 25.7.2006, 07:27
Столкнулся с проблемой, что не знаю как передать указатель (Pointer) на структуру в API функция

Ситуация:

Есть функция 
Код

BOOL GetPrinter(
  HANDLE hPrinter,    // handle to printer
  DWORD Level,        // information level
  LPBYTE pPrinter,    // printer information buffer
  DWORD cbBuf,        // size of buffer
  LPDWORD pcbNeeded   // bytes received or required
);


в которую передается указатель на структуру pPrinter, ради получания информации о принтере!

Проблема:

не могу инициализировать  smile  структуру pPrinter, функция не выполняется, а GetLastError выдает сообщение о том, что я неправильный указатель на структуру предоставил (ошибка 1780 если интересно)

Цель:

научите меня эти структуры инициализировать, хочу понять, чтоб не только эту функцию мог выполнить, но и с другими все получилось, лучше сами но если пошлете на книгу или статью, то всирано спасиб!  smile  

Автор: BUGOR 25.7.2006, 08:25
Цитата

The GetPrinter function retrieves information about a specified printer. 

BOOL GetPrinter(

    HANDLE hPrinter,    // handle to printer of interest 
    DWORD Level,    // version of printer info data structure 
    LPBYTE pPrinter,    // pointer to array of bytes that receives printer info. structure 
    DWORD cbBuf,    // size, in bytes, of array of bytes 
    LPDWORD pcbNeeded  // pointer to variable with count of bytes retrieved (or required) 
   );    
 

Parameters

hPrinter

Handle to the printer of interest. 

Level

Specifies the level, or type, of PRINTER_INFO_* structure that the function stores into the buffer pointed to by pPrinter. 
Windows 95: This value can be 1, 2, or 5.
Windows NT: This value can be 1, 2, 3, 4, or 5. 

pPrinter

Pointer to a buffer that receives a PRINTER_INFO_* structure. This structure contains information about the specified printer. The type of structure is determined by the value of Level. 
Windows 95: The buffer can receive a PRINTER_INFO_1, PRINTER_INFO_2, PRINTER_INFO_5 structure.
Windows NT: The buffer can receive a PRINTER_INFO_1, PRINTER_INFO_2, PRINTER_INFO_3, PRINTER_INFO_4, or PRINTER_INFO_5 structure.

cbBuf

Specifies the size, in bytes, of the buffer pointed to by pPrinter. 

pcbNeeded

Pointer to a variable that the function sets to the size in bytes of the printer information. If cbBuf is smaller than this value, GetPrinter fails, and the value represents the required buffer size. If cbBuf is equal to or greater than this value, GetPrinter succeeds, and the value represents the number of bytes stored into the buffer.


Сами структуры PRINTER_INFO без особого труда найдёшь в C:\Program Files\Borland\Delphi6\Source\Rtl\Win\WinSpool.pas
Надеюсь из этого описания всё понятно? Это не указатель на структуру, это указатель на байтовый массив, который будет хранить в себе структуру, вообщем читай описания, там всё подробно описано. 

Автор: BpIstorick 25.7.2006, 10:32
BUGOR, 

Я знаю на какую структуру мне нужно передать указатель, я не знаю как правильно это сделать
 все эти функции я успешно нашел в MSDN, собственно оттуда я и взял описание функции GetPrinter для своего вопроса smile , мне хочется узнать не конкретный случай, а именно подход!

Код

Pointer to a buffer that receives a PRINTER_INFO_* structure. 
This structure contains information about the specified printer. The type of structure is determined by the value of Level. 


то есть указатель на буффер "a PRINTER_INFO_* structure", то есть буффер болжен быть просто массивом байт нужного размера (допустим buffer: array [0..Size] of byte), а потом мы передаем этот буфер соответствующей структуре или buffer должен быть сразу типа PPrinterInfo2? в DRKB есть пример как добавить принтер с помощью API функции AddPrinter, 

НО мы сами создаем в этом примере и заполняем структуру

А МНЕ НУЖНО ПОЛУЧИТЬ структуру из GetPrinter  smile 

p.s. повторю что мне интересен подход и методика, чтобы в будущем не спрашивать по каждой функции разъяснений ;) 

Автор: Alexeis 25.7.2006, 10:59
что-то вроде этого.
Код

var
  p          :  TPrinterInfo1;
  NewStrSize : Cardinal;
begin
  P.Flags := ...;
  P.pDescription := 'что-то там';
  p.pName := 'еще что нибудь';
  p.pComment := 'что угодно';
  GetPrinter(<Handle принтера>, 1, @P, SizeOf(p), NewStrSize);
end;


Цитата(BpIstorick @  25.7.2006,  10:32 Найти цитируемый пост)
А МНЕ НУЖНО ПОЛУЧИТЬ структуру из GetPrinter


Так в P мы получим и результат, который уже будет иметь размер NewStrSize

Добавлено @ 11:00 
Т.е. это уже будет другая структура с другими данными. 

Автор: BpIstorick 25.7.2006, 13:38
т.е. нам нужно как бы инициализировать каждое поле записи типа TPrinterInfo1 (или любой другой нужной). попробую smile отпишусь по результатам.

А если Тип состоит из 30 и до бесконечности количества полей, то нужно будет каждое инициализировать отдельно??? 

Автор: BpIstorick 25.7.2006, 14:16
Нашел ответ опять же в DRKB, статья называется "Как изменить порт для принтера?" (хотя там подобного материала как оказалось навалом, просто или не попадалось на глаза, или не обращал внимание)

код, написанный мной для проверки работает и выглядит следующим образом smile

Код

procedure TForm1.btnGetInfoClick(Sender: TObject);
var
  pInfo: PPrinterInfo2;
  pHandle: THandle;
  need: DWord;
begin
  OpenPrinter ('Принтер Samsung ML-1210', pHandle, nil);
  label1.Caption:= inttostr (pHandle);
  GetPrinter (pHandle, 2, nil, 0, @need);
  Label2.Caption:= InttoStr (need);
  pInfo:= AllocMem (need);
  GetPrinter (pHandle, 2, pInfo, need, @need);
  label3.Caption:='aa'+pInfo^.pPrinterName;
  label4.Caption:='aa'+pInfo^.pServerName;
  label5.Caption:='aa'+pInfo^.pShareName;
  label6.Caption:='aa'+pInfo^.pPortName;
  label7.Caption:='aa'+pInfo^.pDriverName;
  label8.Caption:='aa'+pInfo^.pPrintProcessor;
  FreeMem (pInfo);
end;


как оказалось все просто и непросто (если не знаешь как делать smile )

1. первым вызовом получаем необходимое количесвто байт по структуру pInfo
2. выделяем необходимое количество байт
3. получаем саму структуру smile 

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