Ask the PowerBuilder Pro 10-Minute Solution

Copy a Window Image to Word
By Ken Howe

This month's 10-Minute Solution demonstrates how to take a snapshot of a window in your application and paste it into Microsoft Word. In order to achieve this, you will require some help from the Windows API and some use of OLE automation. (Quite a few people have asked about this and it is a complex subject, so perhaps this should be more properly called a "20-Minute Solution"!)

Start off by creating a new window. Add a button labeled cb_capture to the window. The first task is to capture the image from PowerBuilder and store it in the Clipboard so it'll be ready to be displayed in Word. Doing this requires a few API calls.

Open the local external functions window and enter the following API calls:

 
Function long CreateCompatibleDC( uint hDC ) Library 'gdi32'
Function long GetWindowDC( long lhWnd ) Library "user32"
Function long ReleaseDC( long lhWnd, uint hDC ) Library "user32"
Function long CreateCompatibleBitmap( uint hDC, integer iWidth, integer
iHeight ) Library "gdi32"
Function long SelectObject( uint hDC, uint hObj ) Library 'gdi32'
Function boolean DeleteObject( long hDC ) Library 'gdi32'
Function boolean DeleteDC( long hDC ) Library 'gdi32'
Function boolean BitBlt( uint hDestDC, int ix, int iy, int iw, int ih, uint
hSourceDC, int idx, int idy, long oper ) Library 'gdi32'

Function boolean OpenClipboard( long lhWnd ) Library 'user32'
Function long SetClipboardData( uint uiFormat, long hBmp ) Library 'user32'
Subroutine CloseClipboard() Library 'user32'
Subroutine EmptyClipboard() Library 'user32'
The first block of API calls captures the screen image and creates a bitmap from that image. The second set of API calls copies that bitmap image to the Clipboard in a clipboard-compatible format.

Open the clicked event for your button cb_capture and declare the following variables:

 
Integer li_W, li_H
Long ll_DC, ll_BMP, ll_DestDC, ll_RC
Boolean lb_RC
String ls_Type = 'DISPLAY'
OLEObject lole_Word
The routines you are using from the Windows API capture a rectangular area of the current screen, so to capture the current window you need to convert the window's width and height into pixels so they're ready for the routines. Add the following code to achieve this:

li_W = UnitsToPixels( parent.Width, XUnitsToPixels! ) li_H = 
     UnitsToPixels( parent.Height, YUnitsToPixels! )
Start to call the API. Ask the API for a handle to the device context of the current window:

ll_DC = GetWindowDC( Handle( parent ) )
This returns a pointer to an object that has details about the current screen setup—such as the number of colors—but this isn't really important to know because the next function call is used to create your own device context. It just makes a new one that is the same as the current one:

ll_DestDC = CreateCompatibleDC( ll_DC )
Create a new bitmap object based on the screen Device Context. You will use a later API call to make a copy of the rectangle you want into this bitmap, so make sure the new bitmap is the same size as the area you are going to copy.

After creating the bitmap, associate it with your newly created Device Context:

ll_BMP = CreateCompatibleBitmap( ll_DC, li_W, li_H )
SelectObject( ll_DestDC, ll_BMP )
Finally, copy the rectangle that you want to capture into the bitmap object using the BitBlt API call:

BitBlt( ll_DestDC, 0, 0, li_W, li_H, ll_DC, 0, 0, 13369376 )
Now you have a bitmap object in memory that is a copy of the current window. (You can copy any rectangular area this way, if you want.)

The next section of code takes this bitmap and puts it on the Clipboard ready to be pasted into Word. To do this you must ask for a handle to the Clipboard, empty any current Clipboard contents, and set your bitmap as the new Clipboard contents. You cannot use the built-in PowerBuilder function because it does not know about bitmap objects.

lb_RC = OpenClipBoard( Handle( parent ) )
IF lb_rc THEN
EmptyClipBoard()
SetClipBoardData( 2, ll_BMP )
CloseClipBoard()
ELSE
MessageBox( 'ClipBoard', 'Error Opening ClipBoard' )
DeleteObject( ll_BMP )
RETURN
END IF
If the OpenClipboard function fails and will not let you add your bitmap object, you must clean up the bitmap in memory using the DeleteObject call. If you are successful, Windows will clean it up for you so you can forget about it.

Finally, clean up the two Device Contexts you used:

DeleteDC( ll_DestDC )
ReleaseDC( Handle( parent ), ll_DC )
Now that you have the image in the Clipboard it is a simple matter to create an OLE automation to Microsoft Word and ask it to paste your image into Word before displaying the application.

Create an OLE Object and connect it to Word:

lole_Word = CREATE OleObject ll_RC = 
   lole_Word.ConnectToNewObject( 'Word.Application' )
IF ll_RC <> 0 THEN
DESTROY lole_Word
RETURN
END IF
If the connection is successful, use OLE automation to paste the contents from the Clipboard directly into Word and finally display Word:
lole_Word.Documents.Add()
lole_Word.Selection.Paste()
lole_Word.Application.Visible = True
lole_Word.DisconnectObject()
DESTROY lole_Word
Now that you have your complete routine, save the script and the window, run the application, and click the button to test it.
 
Other 10-Minute Solutions
 Building a Systray Icon
 Export Data to Excel Through OLE Automation
 Using the Microsoft Browser Control with PowerBuilder
 Copy a Window Image to Word
 Sending E-mail with MAPI
 Receiving E-mail with MAPI
 Interfacing with and Sending Data to Microsoft Word
 Reading Data From a Word Document Into a Datawindow Control
 Font List Extraction: Part I
 Font List Extraction: Part II
 Font List Extraction: Part III
 Font List Extraction: Part IV


Ask the PowerBuilder Pro | Who is the Pro? | Usage Policies | Ask a Question | Search | Feedback


Sponsored Links


Advertising Info  |   Member Services  |   Contact Us  |   Help  |   Feedback  |   Site Map
Jupiterweb networks

internet.comearthweb.comDevx.comClickZ

Search Jupiterweb:

Jupitermedia Corporation has four divisions:
JupiterWeb, JupiterResearch, JupiterEvents, and JupiterImages

Copyright 2004 Jupitermedia Corporation All Rights Reserved.
Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

Jupitermedia Corporate Info | Newsletters | Tech Jobs | E-mail Offers