Форум: "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