Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2009.05.03;
Скачать: [xml.tar.bz2];

Вниз

Сохранение/чтение DEVMODE   Найти похожие ветки 

 
Циркуль   (2008-04-22 18:34) [0]

Собсно, стоит задача один раз задав настройки печати для принтера, их потом использовать. Для этого, видимо, надо как-то уметь хранить DEVMODE. Сделал тестовую прогу. По нажатию одной кнопки вызываем диалог свойств принтера, по закрытии которого полученный DEVMODE пишем в файл. По нажатию второй кнопки читаем из файла DEVMODE, и подсовываем его в диалог свойств принтера. Код модуля:


unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   btnSaveDevMode: TButton;
   edPrinterName: TEdit;
   btnGetDevMode: TButton;
   procedure btnSaveDevModeClick(Sender: TObject);
   procedure btnGetDevModeClick(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

uses
 winspool;

procedure TForm1.btnSaveDevModeClick(Sender: TObject);
var
 StubDevMode: TDeviceMode;
 DevMode: PDevMode;
 hPrinter: THandle;
 dmSize: Cardinal;
 Stream: TFileStream;
begin
 if OpenPrinter(PChar(edPrinterName.Text), hPrinter, nil) then
 begin
   try
     dmSize := DocumentProperties(Handle, hPrinter, PChar(edPrinterName.Text), StubDevMode, StubDevMode, 0);
     GetMem(DevMode, dmSize);
     try
       case DocumentProperties(Handle, hPrinter, PChar(edPrinterName.Text), DevMode^, StubDevMode,
                               DM_OUT_BUFFER or DM_IN_PROMPT) of
         IDOK:
           begin
             Stream := TFileStream.Create("C:\11111.ini", fmCreate);
             try
               Stream.Write(DevMode, dmSize);
             finally
               Stream.Free;
             end;
           end;
         IDCANCEL:
           Exit;
         else
           ShowMessage("Ошибка при получении свойств принтера");
       end;
     finally
       FreeMem(DevMode);
     end;
   finally
     ClosePrinter(hPrinter);
   end;
 end
 else
   ShowMessageFmt("Не удалось открыть принтер "%s"", [edPrinterName.Text]);
end;

procedure TForm1.btnGetDevModeClick(Sender: TObject);
var
 StubDevMode: TDeviceMode;
 DevMode: PDevMode;
 hPrinter: THandle;
 dmSize: Cardinal;
 dmFileSize: Integer;
 Stream: TFileStream;
begin
 if OpenPrinter(PChar(edPrinterName.Text), hPrinter, nil) then
   try
     dmSize := DocumentProperties(Handle, hPrinter, PChar(edPrinterName.Text), StubDevMode, StubDevMode, 0);
     GetMem(DevMode, dmSize);
     try
       Stream := TFileStream.Create("C:\11111.ini", fmOpenRead);
       try
         if dmSize = Stream.Size then
         begin
           Stream.Seek(0, soFromBeginning);
           Stream.ReadBuffer(DevMode, dmSize);
           case DocumentProperties(Handle, hPrinter, PChar(edPrinterName.Text), DevMode^, DevMode^,
                              DM_IN_BUFFER or DM_OUT_BUFFER or DM_IN_PROMPT) of
             IDOK: Caption := "OK";
             IDCANCEL: Caption := "Cancel"
             else
               Caption := "Err"
           end;
         end
         else
           ShowMessage("Ошибка: отличаются размеры DEVMODE выбранного принтера и полученные из файла");
       finally
         Stream.Free;
       end;
     finally
       FreeMem(DevMode);
     end;
   finally
     ClosePrinter(hPrinter);
   end
 else
   ShowMessageFmt("Не удалось открыть принтер "%s"", [edPrinterName.Text]);
end;

end.


Пока оба действия происходят в рамках одного запуска приложения - все работает. Но если приложение закрыть, запустить заново и нажать вторую кнопку - DEVMODE прочитается из файла, но в диалоге все равно будут значения по умолчанию. Причем в этом случае при закрытии диалога само по себе закрывается и приложение, без каких-либо ошибок.


 
Игорь Шевченко ©   (2008-04-22 20:31) [1]

Я конечно извиняюсь, но TStream.ReadBuffer объявлен как
ReadBuffer(var Buffer; Count: Longint);

а Write как function Write(const Buffer; Count: Longint): Longint;

То есть, при Write неплохо бы говорить Write (DevMode^, ...)
а при ReadBuffer, соответственн, ReadBuffer (DevMode^, ...)
В твоем случае ты пишешь указатель и мусор в стеке за ним, а при чтении затираешь память


 
Циркуль   (2008-04-22 21:37) [2]

ээээ... спасибо, конечно :)
а как это объясняет нормальную работу в случае когда жмем вторую кнопку, не закрывая приложение?
devmode тогда должен был бы заполняться мусором из файла, который туда попал при сохранении...


 
Циркуль   (2008-04-22 21:41) [3]

блин, неужели из-за того, что при GetMem(DevMode, dmSize) во втором случае просто выделяется тотже самый кусок памяти, который освободился после вызова первой процедуры?
жесть, сам бы ни за что не допер :)


 
Игорь Шевченко ©   (2008-04-22 22:19) [4]

Циркуль   (22.04.08 21:41) [3]

Нет, он не выделяется. В указатель читается его значение из файла, а возможно, память к тому времени еще не успела перезаписаться.


 
Циркуль   (2008-04-22 23:30) [5]

А, ну да... Ну все равно "везение" :)

Еще раз спасибо



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2009.05.03;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.007 c
15-1234853071
24ruswebmaster
2009-02-17 09:44
2009.05.03
This is a multi-part message in MIME format


4-1209045469
AlexK
2008-04-24 17:57
2009.05.03
MAPI_E_INVALID_ENTRYID


2-1237449117
немо2
2009-03-19 10:51
2009.05.03
ADO в MSSQL2000. Как получить ответ в мемо


2-1237800927
Iriss
2009-03-23 12:35
2009.05.03
InputBox


2-1237613234
Cabyrc
2009-03-21 08:27
2009.05.03
Могу ли я извлечь данные, из БД не зная напрямую название имеющей





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский