Printing with DUIM. 
Author Message
 Printing with DUIM.

Quote:
> A question has popped up while I've been hacking.  How do I print
> (to a printer) using DUIM?  I've gathered it has something to do
> with <medium> subclass instances, but the details currently escape
> me.

> Mind you, it occurs to me that in HD itself I can't print source
> files (not that I can see anyway).  Does this bode ill for printing?

Printing is one piece of DUIM that we never got around to, but in the
interim we created a version of the Scribble example that uses the
Win32 FFI to print the contents of a DUIM window. This will be in the
2.0 beta release (coming really soon now), but in the interim I've
included the source code for the project.

Hope this helps,

Andy

P.S. This code doesn't work on Windows 95, I have yet to track down
why. If you need it there let me know. Also, I haven't tried this code
in 1.2, so let me know if you have any problems.

library.dylan
------------------------------8<------------------------------
Module:    dylan-user
Author:    Scott McKay
Synopsis:  Win32 version of the DUIM scribble application
Copyright: Copyright (c) 1996-1999 Harlequin Group plc.  All rights reserved.

define library win32-scribble
  use harlequin-dylan;
  use duim;

  use c-ffi;
  use win32-common;
  use win32-user;
  use win32-gdi;
  use win32-kernel;
  use win32-dialog;

  export win32-scribble;
end library win32-scribble;

define module win32-scribble
  use harlequin-dylan;
  use duim;
  use win32-duim;
  use duim-internals,
    import: { sheet-mirror };

  use C-FFI;
  use win32-common,
    rename: { <point> => w/<point> };
  use win32-user;
  use win32-gdi,
    rename: { <PATTERN> => w/<PATTERN> };
  use win32-kernel,
    rename: { Beep  => w/Beep,
              Sleep => w/Sleep };
  use win32-dialog;

  export <scribble-pane>,
         <scribble-frame>,
         scribble;
end module win32-scribble;
------------------------------8<------------------------------

scribble.dylan
------------------------------8<------------------------------
Module:    win32-scribble
Author:    Scott McKay
Synopsis:  Win32 version of the DUIM scribble application
Copyright: Copyright (c) 1996-1999 Harlequin Group plc. All rights reserved.

/// Simple scribble application

define class <scribble-pane> (<drawing-pane>)
  slot scribble-segment = #f;
  constant slot scribble-segments = make(<stretchy-vector>);
  constant slot scribble-popup-menu-callback = #f,
    init-keyword: popup-menu-callback:;
end class <scribble-pane>;

define method draw-segment
    (medium :: <medium>, segment :: <sequence>) => ()
  draw-polygon(medium, segment, closed?: #f, filled?: #f)
end method draw-segment;

// Draw the scribble as several unconnected polylines
define method handle-repaint
    (sheet :: <scribble-pane>, medium :: <medium>, region :: <region>) => ()
  ignore(region);
  for (segment in sheet.scribble-segments)
    draw-segment(medium, segment)
  end
end method handle-repaint;

define method handle-button-event
    (sheet :: <scribble-pane>,
     event :: <button-press-event>,
     button == $left-button) => ()
  sheet.scribble-segment := make(<stretchy-vector>);
  add-scribble-segment(sheet, event.event-x, event.event-y)
end method handle-button-event;

define method handle-button-event
    (sheet :: <scribble-pane>,
     event :: <pointer-drag-event>,
     button == $left-button) => ()
  add-scribble-segment(sheet, event.event-x, event.event-y)
end method handle-button-event;

define method handle-button-event
    (sheet :: <scribble-pane>,
     event :: <button-release-event>,
     button == $left-button) => ()
  when (add-scribble-segment(sheet, event.event-x, event.event-y))
    add!(sheet.scribble-segments, sheet.scribble-segment)
  end;
  sheet.scribble-segment := #f
end method handle-button-event;

define method handle-button-event
    (sheet :: <scribble-pane>,
     event :: <button-release-event>,
     button == $right-button) => ()
  let popup-menu-callback = scribble-popup-menu-callback(sheet);
  when (popup-menu-callback)
    popup-menu-callback(sheet, event.event-x, event.event-y)
  end
end method handle-button-event;

define method add-scribble-segment
    (sheet :: <scribble-pane>, x, y) => (did-it? :: <boolean>)
  let segment = sheet.scribble-segment;
  // The app can generate drag and release events before it has ever
  // seen a press event, so be careful
  when (segment)
    add!(segment, x);
    add!(segment, y);
    draw-segment(sheet-medium(sheet), segment);
    #t
  end
end method add-scribble-segment;

define method clear-surface (sheet :: <scribble-pane>) => ()
  sheet.scribble-segments.size := 0;
  clear-box*(sheet, sheet-region(sheet))
end method clear-surface;

/// A top-level frame
define frame <scribble-frame> (<simple-frame>)
  pane surface (frame)
    make(<scribble-pane>,
         popup-menu-callback: method (sheet, x, y)
                                let frame = sheet-frame(sheet);
                                popup-scribble-menu(frame, x, y)
                              end,
         width:  300, max-width:  $fill,
         height: 200, max-height: $fill);
  pane print-menu-box (frame)
    make(<menu-box>,
         children: vector(make(<menu-button>,
                               label: "Page Setup...",
                               activate-callback: method (button)
                                                    scribble-page-setup(frame)
                                                  end),
                          make(<menu-button>,
                               label: "Print...",
                               activate-callback: method (button)
                                                    scribble-print(frame)
                                                  end)));
  pane file-menu (frame)
    make(<menu>,
         label: "File",
         children: vector(make(<menu-button>,
                               label: "Clear",
                               activate-callback: method (button)
                                                    clear-surface(frame.surface)
                                                  end),
                          frame.print-menu-box,
                          make(<menu-button>,
                               label: "Exit",
                               activate-callback: method (button)
                                                    exit-frame(sheet-frame(button))
                                                  end)));
  pane scribble-popup-menu (frame)
    make(<menu>,
         owner: frame.surface,
         children: vector(make(<menu-button>,
                               label: "&Clear",
                               activate-callback: method (button)
                                                    ignore(button);
                                                    clear-surface(frame.surface)
                                                  end)));
  layout (frame) frame.surface;
  menu-bar (frame)
    make(<menu-bar>, children: vector(frame.file-menu));
end frame <scribble-frame>;

define method popup-scribble-menu
    (frame :: <scribble-frame>, x :: <integer>, y :: <integer>) => ()
  let menu = frame.scribble-popup-menu;
  display-menu(menu, x: x, y: y)
end method popup-scribble-menu;
------------------------------8<------------------------------

printing.dylan
------------------------------8<------------------------------
Module:    win32-scribble
Author:    Andy Armstrong
Synopsis:  Printer support for scribble
Copyright: Copyright (c) 1999 Harlequin Group plc. All rights reserved.

define macro with-printing
  { with-printing (?dc:name, ?name:expression)
      ?body:body
    end }
 => { do-with-printing(?dc, ?name, method (?dc) ?body end) }
end macro with-printing;

define method scribble-page-setup
    (frame :: <scribble-frame>) => ()
  notify-user("Not yet implemented!",
              style: #"warning", exit-style: #"ok")
end method scribble-page-setup;

define method scribble-print
    (frame :: <scribble-frame>) => ()
  let dc = choose-printer-options(frame);
  if (dc)
    with-printing (dc, "scribble")
      let sheet = frame.surface;
      let (x-scale, y-scale) = sheet-printer-scaling(sheet, dc);
      repaint-in-dc-recursive(sheet, dc, x-scale, y-scale, 0, 0)
    end
  end
end method scribble-print;

/// Win32 code

define function ensure-no-dialog-error (name :: <string>) => ()
  let error = CommDlgExtendedError();
  unless (error = $NO-ERROR)
    report-error(name, error: error)
  end
end function ensure-no-dialog-error;

define method choose-printer-options
    (frame :: <scribble-frame>)
 => (dc :: false-or(<HDC>))
  let sheet = top-level-sheet(frame);
  let handle = window-handle(sheet);
  with-stack-structure (devmode :: <LPDEVMODE>)
    with-stack-structure (devnames :: <LPDEVNAMES>)
      with-stack-structure (print :: <LPPRINTDLG>)
        print.lStructSize-value  := size-of(<PRINTDLG>);
        print.hwndOwner-value    := handle;
        print.hInstance-value    := application-instance-handle();
        print.hDevMode-value     := devmode;
        print.hDevNames-value    := devnames;
        print.Flags-value        := %logior($PD-USEDEVMODECOPIESANDCOLLATE,
                                            $PD-RETURNDC);
        print.nCopies-value      := 1;
        print.nFromPage-value    := 1;
        print.nToPage-value      := 1;
        print.nMinPage-value     := 1;
        print.nMaxPage-value     := 1;
        if (PrintDlg(print))
          print.hDC-value;
        else
          ensure-no-dialog-error("PrintDlg");
          #f
        end
      end
    end
  end
end method choose-printer-options;

define method do-with-printing
    (dc :: <HDC>, name :: <string>, function :: <function>) => ()
  let started? :: <boolean> = #f;
  block ()
    with-stack-structure (docinfo :: <LPDOCINFO>)
      with-c-string (c-string = name)
        docinfo.cbSize-value       := size-of(<DOCINFO>);
        docinfo.lpszDocName-value  := c-string;
        docinfo.lpszOutput-value   := $NULL-string;
        docinfo.lpszDatatype-value := $NULL-string;
        docinfo.fwType-value       := 0;
        StartDoc(dc, docinfo);
        started? := #t;
      end
    end;
    function(dc)
  cleanup
    if (started?)
      EndDoc(dc)
    end;
    DeleteDc(dc)
  end
end method do-with-printing;

define method sheet-printer-scaling
    (sheet :: <sheet>, printer-dc :: <HDC>)
 => (x-scale :: <single-float>, y-scale :: <single-float>)
  let mirror = sheet-mirror(sheet);
  let sheet-dc = get-dc(mirror);
  local method scale
            (value1 :: <integer>, value2 :: <integer>)
         => (scale :: <single-float>)
          as(<single-float>, value1) / as(<single-float>, value2)
        end method scale;
  values(scale(GetDeviceCaps(printer-dc, $LOGPIXELSX),
               GetDeviceCaps(sheet-dc,   $LOGPIXELSX)),
         scale(GetDeviceCaps(printer-dc, $LOGPIXELSY),
               GetDeviceCaps(sheet-dc,   $LOGPIXELSY)))
end method sheet-printer-scaling;
------------------------------8<------------------------------



Mon, 26 Nov 2001 03:00:00 GMT  
 
 [ 1 post ] 

 Relevant Pages 

1. Printing with DUIM.

2. problem with DUIM at higher resolutions

3. DUIM focus question

4. A duim menu question

5. updating an icon label in DUIM

6. updating an icon label in DUIM

7. DUIM font question

8. DUIM question

9. help with DUIM application

10. DUIM clipboard

11. <tree-node> in DUIM

12. Browser gadget sugguestions for a DUIM app

 

 
Powered by phpBB® Forum Software