Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

4VPS.SU - VPS в 17-ти странах

2Gbit/s безлимит

Современное железо!

Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

✅ Дешевый VPS-хостинг на AMD EPYC: 1vCore, 3GB DDR4, 15GB NVMe всего за €3,50!

🔥 Anti-DDoS защита 12 Тбит/с!

Глава 5. Повторное отображение графики

             В следующих трех шагах вы узнаете как

             * Отображать по запросу графический образ.

             * Сохранять образ файла и загружать его.

             * Печатать образ.

                            Шаг 7: Вывод на экран графики
        -----------------------------------------------------------------

                            +-----------------------+
                            | Step 1: Basic App     |
                            | Step 2: Text          |
                            | Step 3: Lines         |
                            | Step 4: Menu          |
                            | Step 5: About Box     |
                            | Step 6: Pens          |
                            |XStepX7:XPaintingXXXXXX|
                            | Step 8: Streams       |
                            | Step 9: Printing      |
                            | Step 10: Palette      |
                            | Step 11: BWCC         |
                            | Step 12: Custom ctrls |
                            +-----------------------+

             Возможно, вы удивитесь,  узнав, что графика и текст, которые
        вы рисуете  в  окне  с  помощью  функций Windows типа TextOut или
        LineTo, исчезают при изменении размера окна или повторного вывода
        его на   экран.  После  того,  как  графические  данные  переданы
        Windows,  через вызовы функций Windows вы никогда не получаете их
        обратно для повторного отображения.

             Чтобы в окне повторно отображалась графика, вы должны сохра-
        нить эту графику (или данные для регенерации графики) в структуре
        некоторого типа,  такой как объект.  С помощью объектов вы можете
        полиморфически хранить простую или сложную графику,  а также хра-
        нить объекты и поля ваших оконных объектов.

                               Изображение и рисование
        -----------------------------------------------------------------

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

             Окна должны иметь возможность воссоздавать по  запросу  свои
        графические образы. Windows сообщает своим оконным объектам, ког-
        да они требуют изображения или обновления.  При этом окно  должно
        каким-то образом генерировать образ экрана.  В ответ на необходи-
        мость изображения.  ObjectWindows  автоматически  вызывает  метод
        Paint вашего окна. Наследуемый и TWindow метод Paint не выполняет
        никаких функций. В Paint вы должны поместить код для передачи со-
        держимого окна. Фактически Paint вызывается при первом выводе ок-
        на. Paint отвечает за обновление (при необходимости)  изображения
        текущим содержимым.

             Существует еще одно важное отличие между отображением графи-
        ки в методе Paint и другим ее отображением (например, в ответ  на
        действия "мышью").  Содержимое  экрана,  которое должно использо-
        ваться для отображения,  передается в параметре PaintDC,  так что
        вашей программе не требуется получать или освобождать его. Однако
        вам потребуется вновь выбрать для PaintDC изобразительные  средс-
        тва.

             Чтобы отобразить  содержимое  окна,  вместо  повторения  тех
        действий, которые привели к первоначальному изображению (DragDC),
        вы используете PaintDC. Визуальный эффект будет тот же, что и при
        первоначальном рисовании пользователем  (аналогично  проигрыванию
        аудиозаписи концерта).  Но чтобы "проигрывать" ее в методе Paint,
        сначала вам нужно сохранить графику в виде объектов.

                            Сохранение графики в объектах
        -----------------------------------------------------------------

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

             Для размещения неизвестного числа линий или точек  прекрасно
        подходит определенный в модуле Objects тип TCollection. Это набор
        объектов, который может динамически расширяться,  когда вы добав-
        ляете другие элементы.  Этим наборам не важно,  что они включают,
        поэтому вы можете использовать один и тот же механизм и  для  ри-
        сунка (набора линий), и для линии (набора точек).

                   Примечание: О наборах рассказывается в Главе 19 "Набо-
              ры".

             Концептуально вам нужно просто сделать так, чтобы окно знало
        о своем содержимом, так что оно сможет обновить изображение. Окно
        содержит рисунок,  представляющий собой набор линий.  Таким обра-
        зом, вам нужно:

             * Передать окну объект или поле, содержащее набор линий.

             * Определить объект линии, который может отображаться.

             * В ответ на сообщения "мыши" добавлять к сохраненным линиям
               точки.

                               Добавление поля объекта
        -----------------------------------------------------------------

             Чтобы сохранить рисунок в  виде  набора  линий,  добавьте  в
        TStepWindow поле с именем Drawing.  В любой момент Drawing содер-
        жит текущий рисунок в виде набора объектов линий. Когда требуется
        отобразить окно, оно использует для изображения линии данные, за-
        писанные в Drawing.

                              Определение объекта линии
        -----------------------------------------------------------------

             Далее нужно ответить на вопрос, что такое линия. В шаге 4 вы
        видели, что  изображаемая  линия  представляет собой просто набор
        точек, передаваемых  из  Windows  в  программу  через   сообщение
        wm_MouseMove. Для представления линий и точек вам необходимы объ-
        ектные типы.  Поскольку эффективный объект изображения линии дол-
        жен быть повторно используемой частью, создайте отдельный модуль,
        определяющий объекты линий и точек.

             TLine содержит всю информацию,  необходимую для  изображения
        данной линии: перо и набор точек.

             type
               PLine = ^TLine;
               TLine = object(TObject)
                   Points: PCollection;
                   LinePen: PPen;
                   constructor Init(APen: PPen);
                   constructor Load(var S: TStream);
                   destructor Done; virtual;
                   procedure AddPoint(AX, AY: Word);
                   procedure Draw(ADC: HDC);
                   procedure Store(var S: TStream);
             end;

             LinePen просто указывает на объект TPen, а Point - это набор
        объектов точек.  TLine и TLinePoint содержат методы Load и Store,
        преимущества использования которых для записи картинок на диск вы
        увидите в  шаге  8.  В  отличие от них объект TLine весьма прост:
        конструктор и деструктор создают и уничтожают  LinePen,  AddPoint
        включает объект точки в Points, а Draw рисует линии между точками
        Points.

             Объект TLinePoint еще проще:

             type
               PLinePoint = ^TLinePoint;
               TLinePoint = object(TObject)
                  X, Y: Integer;
                  constructor Init(AX, AY: Integer);
                  constructor Load(var S: TStream);
                  procedure Store(var S: TStream);
             end;

             constructor TLinePoint.Init(AX, AY: Integer);
             begin
               X := AX;
               Y := AY;
             end;

             TLinePoint не определяет никакого  нового  поведения  -  это
        просто объект данных,  который должен использоваться в TLine.  Но
        позднее (в шаге 8) он понадобиться как объект для записи в поток.
        Не забудьте построить в TStepWindow.Init Drawing и уничтожить его
        в TStepWindow.Done:

             constructor TStepWindow.Init(AParent: PWindowsObject;
                                          ATitle: PChar);
             begin
               inherites Init(AParent, ATitle);
               ButtonDown := False;
               HasChanged := False;
               CommonPen := New(PPen, Init(ps_Solid, 1, 0));
               Drawing := New(PCollection, Init(50, 50));
             end;

             destructor TStepWindow.Done;
             begin
               Dispose(CommonPen, Done);
               Dispose(Drawing, Done);
               inherited Done;
             end;

             Основное окно  программы  Steps  содержит набор в своем поле
        Drawing набор линий.  Когда пользователь рисует линии,  вы должны
        преобразовывать их в объекты и добавлять в Drawing.  Затем, когда
        потребуется отобразить окно, путем итерации Drawing нужно отобра-
        зить каждую его точку.


                          Изменение методов работы с "мышью"
        -----------------------------------------------------------------

             Чтобы сохранять  линии  в виде объектов,  вы должны изменить
        EMLButtonDown и WMMouseMove,  чтобы не только рисовать линии,  но
        также сохранять  точки  в  наборе линий.  Поскольку текущую линию
        придется обновлять  не   только   одному   методу,   добавьте   в
        TStepWindow еще одно поле типа PLine с именем CurrentLine:

             type
               TStepWindow = object(TWindow);
                  CurrentLine: PLine;
                    .
                    .
                    .
             end;

             Кроме добавления  изображения  линии  WMLButttonDown создает
        при каждом вызове новый объект линии и добавляет его  в  набор  в
        Drawing. WMMouseMove просто добавляет новую точку в конец объекта
        текущей линии и изображает в окне линейные сегменты. Сохраняя все
        точки всех линий,  ваше окно будет записывать информацию, необхо-
        димую для точного воспроизведения картинки.

             procedure TStepWindow.WMLButtonDown(var Msg: TMessage);
             begin
               if not ButtonDown then
               begin
                 ButtonDown := True;
                 SetCapture(HWindow);
                 DragDC := GetDC(HWindow);
                 CommonPen^.Select(DragDC);
                 MoveTo(DragDC, Msg.lParamLo, Msg.lParamHi);
                 CurrentLine := New(PLine, Init(CommonPen));
                 Drawing^.Insert(CurrentLine);
               end;
             end.

             procedure TStepWindow.WMMouseMove(var Msg: TMessage);
             begin
               if ButtonDown then
               begin
                 LineTo(DragDC, Msg.lParamLo, Msg.lParamHi);
                 CurrentLine^.AddPoint(Msg.LParamLo, Msg.LParamHi);
               end;
             end;

                   Примечание: Уничтожать  устаревшие CurrentLine не тре-
              буется, поскольку они записаны в наборе Drawing. Все объек-
              ты линий уничтожаются при уничтожении Drawing.

             WMLButtonUp модификации не требует.  Вам не нужно уничтожать
        все объекты линий при очистке отображаемого окна, поэтому добавь-
        те в CMFileNew вызов метода FreeAll:

             procedure TStepWindow.CMFileNew(var Msg: TMessage);
             begin
               Drawing^.FreeAll;
               InvalidateRect(HWindow, nil, True);
             end;

                              Вывод сохраненной графики
        -----------------------------------------------------------------

             Теперь, когда TStepWindow сохраняет свою текущую строку,  вы
        должны научить  его по команде (этой командой является Paint) ри-
        совать ее.  Давайте напишем для TStepWindow метод Paint,  который
        повторяет действия WMLButtonDown,  WMMouseMove и WMLButtonUp. Пу-
        тем итерации по набору линий Paint воссоздает картинку аналогично
        тому, как  это  делаете вы.  Метод Paint имеет следующий вид (см.
        файл STEP07.PAS):

             procedure TStepWindow.Paint(PaintDC: HDC; var PaintInfo:
                                         TPintStruct);

             procedure DrawLine(P: PLine); far;
             begin
               P^.Draw(PaintDC);
             end;

             begin
               Drawing^.ForEach(@DrawLine);
             end;

                   Примечание: Итерация методов описывается  в  Главе  19
              "Наборы".

             Метод Draw  объекта линии для изображения каждой линии между
        точками также использует итератор ForEach:

             procedure TLine.Draw(ADC: HDC);
             var First: Boolean;

               procedure DrawLine(P: PLinePoint); far;
               begin
                 if First then MoveTo(ADC, P^.X, P^.Y)
                 else LineTo(ADC, P^.X, P^.Y);
                 First := False;
               end;

             begin
               First := True;
               LinePen^.Select(ADC);
               Points^.ForEach(@DrawLine);
               LinePen^.Delete;
             end;
------------------------------------------------------------------------
                          Шаг 8: Сохранение рисунка в файле
        -----------------------------------------------------------------

                            +-----------------------+
                            | Step 1: Basic App     |
                            | Step 2: Text          |
                            | Step 3: Lines         |
                            | Step 4: Menu          |
                            | Step 5: About Box     |
                            | Step 6: Pens          |
                            | Step 7: Painting      |
                            |XStep 8:XStreamsXXXXXXX|
                            | Step 9: Printing      |
                            | Step 10: Palette      |
                            | Step 11: BWCC         |
                            | Step 12: Custom ctrls |
                            +-----------------------+

             Теперь, когда  вы  сохранили представление данных в виде ри-
        сунка как часть оконного объекта, можно легко записать эти данные
        в файл (фактически, в буферизованный поток DOS) и считать его об-
        ратно.

             Данный шаг посвящен добавлению  полей  объектов  для  записи
        состояния сохраняемой информации, модификации сохраняемой в файле
        информации и  методам  открытия.  Используя   предусмотренные   в
        ObjectWindows потоковые объекты,  вы убедитесь в удобстве их при-
        менения для сохранения данных в файле.

                                Отслеживание состояния 
        -----------------------------------------------------------------

             Требуется отслеживать две характеристики рисунка.  Изменение
        файла мы  уже  отслеживали  (в  шаге  1   было   добавлено   поле
        HasChanged), но теперь нужно знать, загружен ли файл в данный мо-
        мент. Как и HasChanged,  IsNewFile - это атрибут TStepWindow типа
        Boolean, поэтому его также следует сделать полем:

             TStepWindow = object(TWindow)
                 ButtonDown, HasChanged, IsNewFile: Boolean;
                  .
                  .
                  .
             end.

             Поле HasChanged принимает значение True,  если текущий рису-
        нок модифицирован. Модификация означает, что рисунок был  изменен
        с момента последнего сохранения или не сохранялся вовсе.  Вы  уже
        устанавливаете поле HasChanged в True, когда пользователь начина-
        ет рисовать,  и в False, когда окно очищается. Когда пользователь
        открывает новый файл или сохраняет существующий,  HasChanged сле-
        дует установить в False.

             IsNewFile указывает,  что рисунок не взят из файла,  поэтому
        сохранение рисунка  потребует  от  пользователя задать имя файла.
        IsNeFile имеет значение True только  при  первоначальном  запуске
        приложения и  после  выбора  пользователем  команды меню File|New
        (Файл|Новый). Это поле устанавливается в False, когда файл откры-
        вается или    сохраняется.    Фактически,   FileSave   использует
        IsNewFile, чтобы увидеть, можно ли сохранить файл немедленно, или
        пользователю требуется выбрать файл из файлового диалога.

             Приведем методы  сохранения и загрузки файла.  На данный мо-
        мент они выполняют только сохранение и загрузку файлов.  Сохране-
        ние файла сконцентрировано в одном новом методе,  который называ-
        ется WriteFile, а открытие файла выполняет метод ReadFile.

             procedure TStepWindow.CMFileNew(var Msg: TMessage);
             begin
               if CanClose then
               begin
                 Drawing^.FreeAll;
                 InvalidateRect(HWindow, nil, True);
                 HasChanged := False;
                 IsNewFile := True;
               end;
             end;

             procedure TStepWindow.CMFileOpen(var Msg: TMessage);
             begin
               if CanClose then
                  if Application^.ExecDialog(New(PFileDialog, Init(@Self,
                      PChar(sd_FileOpen), StrCopy(FileName, '*.PTS')))) =
                      id_Ok then ReadFile;
             end;

             procedure TStepWindow.CMFileSave(var Msg: TMessage);
             begin
               if IsNewFile then CMFileSaveAs(Msg) else WriteFile;
             end;

             procedure TStepWindow.CMFileSaceAs(var Msg: TMessage);
             begin
               if IsNewFile then StrCopy(FileName, '');
               if Application^.ExecDialog(New(PFileDialog,
                    Init(@Self, PChar(sd_FileSave), FileName))) =
                    id_Ok then WriteFile;
             end;

             procedure TStepWindow.ReadFile;
             begin
               MessageBox(HWindow, @FileName, 'Загрузить файл:',
                          mb_Ok);
               HasChanged := False;
               IsNewFile := False;
             end;

             procedure TStepWindow.WriteFile;
             begin
               MessageBox(HWindow, @FileName, 'Сохранить файл:',
                          mb_Ok);
               HasChanged := False;
               IsNewFile := False;
             end;

                   Примечание: Данный текст программы можно найти в файле
              STEP08A.PAS.

                             Сохранение и загрузка файлов
        -----------------------------------------------------------------

             Теперь, когда вы создали основную  схему  для  построения  и
        загрузки файлов, осталось только выполнить фактическую загрузку и
        сохранение в файле наборов точек.  Для этого  можно  использовать
        потоковый механизм автоматического сохранения объекта. Сначала вы
        научитесь сохранять и загружать сами объекты точек и  линий  (как
        это сделать для наборов вы уже знаете).  Затем методы WriteFile и
        FileOpen будут модифицированы для использования потоков.

                   Примечание: Подробнее об использовании потоков с  объ-
              ектами рассказывается в Главе 20 "Потоки".

             Ниже приведен  исходный  код,  показывающий  как сохранять и
        загружать сами объекты TLine и TLinePoint:

             const
                RLinePoint: TStreamRec = (
                   ObjType: 200;
                   VmtLink: Ofs(TypeOf(TLinePoint)^);
                   Load: @TLinePoint.Load;
                   Store: @TLinePoint.Store);

                RLine: TStreamRec = (
                   ObjType: 201;
                   VmtLink: Ofs(TypeOf(TLine)^);
                   Load: @TLine.Load;
                   Store: @TLine.Store);

             constructor TLinePoint.Load(var S: TStream);
             begin
               S.Read(X, SizeOf(X));
               S.Read(Y, SizeOf(Y));
             end;

             procedure TLinePoint.Store(var S: TStream);
             begin
               S.Write(X, SizeOf(X));
               S.Write(Y, SizeOf(Y));
             end;

             constructor TLine.Load(var S: TStream);
             begin
               Points := PCollection(S.Get);
               LinePen := PPen(S.Get);
             end;

             procedure TLine.Store(var S: TStream);
             begin
               S.Put(Points);
               S.Put(LinePen);
             end;

             procedure StreamRegistration;
             begin
               RegisterType(RCollection);
             end;

             Для регистрации TCollection при запуске прикладной программы
        вы должны   вызывать   StreamRegistration  (который  находится  в
        Steps). Вы можете поместить это вызов в  метод  TStepWindow.Init.
        Модуль DrawLine   регистрирует   в   своем   коде   инициализации
        TLinePoint и TLine,  поэтому линии и точки регистрируются простым
        включением DrawLine в оператор uses.

             Заключительным шагом  изменения методов WriteFile и ReadFile
        будет фактическая  запись  в  потоки  и  чтение   из   них   (см.
        STEP08B.PAS):

             procedure TStepWindow.ReadFile;
             var
               TempColl: PCollection;
               TheFile: TDosStream;
             begin
               TheFile.Init(FileName, stOpen);
               TempColl: := PCollection(TheFile.Get);
               TheFile.Done;
               if TempColl <> nil then
               begin
                 Dispose(Drawing, Done);
                 Drawing := TempColl;
                 InvalidateRect(HWindow, nil, True);
               end;
               HasChanged := False;
               IsNewFile := False;
             end;

             procedure TStepWindow.WriteFile;
             var
               TheFile: TDosStream;
             begin
               TheFile.Init(FileName, stCreate);
               TheFile.Put(Drawng);
               TheFile.Done;
               IsNewFile := False;
               HasChanged := False;
             end;


------------------------------------------------------------------------
                          Шаг 9: Печать графического образа
        -----------------------------------------------------------------

                            +-----------------------+
                            | Step 1: Basic App     |
                            | Step 2: Text          |
                            | Step 3: Lines         |
                            | Step 4: Menu          |
                            | Step 5: About Box     |
                            | Step 6: Pens          |
                            | Step 7: Painting      |
                            | Step 8: Streams       |
                            |XStepX9:XPrintingXXXXXX|
                            | Step 10: Palette      |
                            | Step 11: BWCC         |
                            | Step 12: Custom ctrls |
                            +-----------------------+

             Печать из Windows может представлять собой  сложную  задачу,
        но ObjectWindows   предоставляет   простой   механизм  добавления
        средств печати в вашу прикладную программу.

             Добавление этих средств предусматривает следующие три шага:

             * Построение объекта принтера.

             * Создание объекта распечатки.

             * Печать объекта распечатки.


                             Построение объекта принтера
        -----------------------------------------------------------------

             Любая программа  ObjectWindows может получить доступ к прин-
        теру с помощью объекта типа TPrinter. В этом случае основное окно
        вашего приложения  должно  построить  объект принтера и сохранить
        его в объектном поле с именем Printer:

             constructor TStepWindow.Init(AParent: PWindowsObject;
                                          ATitle: PChar);
             begin
               inherited Init(AParent, ATitle);
                  .
                  .
                  .
               Printer := New(PPrinter, Init);
             end;

                   Примечание: Тип TPrinter определен в модуле  OPrinter,
              поэтому не забудьте добавить OPrinter в свой оператор uses.

             Это все, что обычно приходится делать для инициализации объ-
        екта принтера.  По умолчанию TPrinter использует  назначенный  по
        умолчанию принтер,  заданный в файле WIN.INI. TPrinter предусмат-
        ривает также механизм для выбора альтернативных принтеров.


                             Создание объекта распечатки
        -----------------------------------------------------------------

             ObjectWindows управляет  выводимыми  на печать данными точно
        также, как выводом на экран. То есть вместо записи непосредствен-
        но на  устройство  вывода (или даже непосредственно в Windows) вы
        направляете свой вывод на объект, который знает, как представлять
        информацию на устройстве вывода. Для вывода на печать используйте
        объекты, полученные из абстрактного типа  TPrintout  и  метода  с
        именем PrintPage.

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

               Примечание: О печати документов рассказывается в Главе 15.

                             Запись в контекст устройства
        -----------------------------------------------------------------

             До настоящего момента вы всегда записывали текст и графику в
        контекст дисплея (что является способом представления  в  Windows
        пользовательской области  окон).  Контекст  дисплея  - это просто
        специализированная версия контекста устройства - механизма, через
        который приложения  Windows  работают  с различными устройствами,
        такими как экраны, принтеры или коммуникационные устройства.

             Запись в контекст одного устройства мало отличается от запи-
        си в контекст другого, поэтому, например, достаточно просто сооб-
        щить, например, оконному объекту, что для записи на принтер нужно
        использовать механизм Paint.

                               Создание распечатки окна
        -----------------------------------------------------------------

             TWindowPrint - это специальный потомок TPrintout, используе-
        мый для печати  содержимого  окна.  Печать  содержимого  окна  не
        представляет сложности по двум причинам:  вы имеете дело только с
        одной страницей, и объект окна уже знает, как отображать свой об-
        раз.

             Обычно при печати документа вашей прикладной программе нужно
        выполнять итерации процесса печати для каждой страницы документа.
        Так как окно имеет только один образ,  при печати окна это не яв-
        ляется необходимым.
             Таким образом,  печать также проста,  как ориентация  метода
        Paint объекта  окна  на  вывод вместо окна в контекст устройства,
        подходящий для принтера:

             procedure TWindowPrint.PrintPage(DC: HDC; Page: Word;
                             Size: TPoint; var Rect: TRect; Flags: Word);
             var PS: TPaintStruct;
             begin
               Window^.Paint(DC, PS);
             end;

             Поскольку переданный  PrintPage параметр DC уже указывает на
        подходящий для принтера контекст устройства,  в простейшем случае
        PrintPage должен только сообщить объекту окна на вывод его содер-
        жимого в этот контекст устройства.  Теперь ваш объект  распечатки
        также знает о своем представлении.

                                   Вывод распечатки
        -----------------------------------------------------------------

             Наличие объекта распечатки, которому известно о своем предс-
        тавлении, это все,  что нужно для передачи распечатки на принтер.
        Программа Steps делает это в ответ на команду cm_FilePrint, гене-
        рируемую командой Print меню File:

             procedure TStepWindow.CMFilePrint(var Msg: TMessage);
             var P: PPrintout;
             begin
               if IsNewFile then StrCopy(FileName, 'Untitled');
               P := New(PWindowPrint, Init(FileName, @Self));
               Printer^.Print(@Self, P);
               Dispose(P, Done);
             end;

             CMFilePrint очень просто строит объект распечатки,  озаглав-
        ленный заданным  именем (имя файла точек или 'Untitled') и запол-
        няет его своим содержимым (так как это единственное  окно в  при-
        ложении).

             При наличии  объекта распечатки CMFilePrint сообщает объекту
        принтера, что его нужно напечатать,  добавив какие-либо сообщения
        об ошибках или диалоговые окна (отсюда параметр @Self). Когда пе-
        чать закончится, CMFilePrint уничтожает объект распечатки.

                                Выбор другого принтера
        -----------------------------------------------------------------

             Одним из средств TPrinter является возможность изменения ус-
        тановки принтера.  TPrinter определяет метод Setup, который выво-
        дит диалоговое окно установки принтера,  позволяющее пользователю
        выбрать принтер из числа установленных в Windows  и  обеспечивает
        доступ к диалоговому окну конфигурации устройства.

             Чтобы вывести диалоговое окно установки принтера, ваша прик-
        ладная программа вызывает метод Setup объекта принтера. Steps де-
        лает это в ответ на команду cm_FileSetup (см. STEP09.PAS):

             procedure TStepWindow.CMFileSetup(var Msg: TMessage);
             begin
               Printer^.Setup(@Self);
             end;

             Диалоговое окно установки принтера является экземпляром типа
        TPrinterSetupDlg (см. Рис. 5.1).

        +---------------------------------------------------------------+
        |#=#XXXXXXXXXXXXXXXXXXXXSelect PrinterXXXXXXXXXXXXXXXXXXXXXXXXXX|
        +---------------------------------------------------------------|
        |                                                               |
        |      Принтер и порт                                           |
        |      +--------------------------------------------+-+         |
        |      |PostScript Printer on LPT1:#################|v|         |
        |      +--------------------------------------------+-+         |
        |    +-----------+        +-----------+      +-----------+      |
        |    |####OK#####|        |##Setup####|      |##Cancel###|      |
        |    +-----------+        +-----------+      +-----------+      |
        |                                                               |
        +---------------------------------------------------------------+

             Рис. 5.1 Диалоговое окно установки принтера.

             В комбинированном блоке диалогового окна выводятся принтеры,
        заданные в WIN.INI.  Это дает пользователю возможность доступа ко
        всем установленным принтерам.
                              Назад | Содержание | Вперед

VPS в России, Европе и США

Бесплатная поддержка и администрирование

Оплата российскими и международными картами

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

Новости мира IT:

Архив новостей

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 7861149
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...