• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 386
  • Last Modified:

Enhanced Meta File of other windows

I want to get the write the data of another app's window to an EMF file (bit-blitting wont work, I need all the data, not just the viewable data).  The code below seems close.  It creates the EMF and writes "Draft".  The message gets posted to the separate app.  The separate app receives it and processes the WM_PRINT message, but nothing get's written to the DC.

What do I need to do?
HENMETAFILE henMF;
HDC hdcRef, hdcMeta;
RECT rBounds;

hdcRef = GetDC(hWnd);

//Retrieve the coordinates of the
//client rectangle in pixels.
GetClientRect(hWnd, &rBounds);

//Create the metafile DC
hdcMeta = CreateEnhMetaFile(hdcRef,
          (LPTSTR)"MYFILE.EMF",
          &rBounds,
          (LPSTR)"My Company Name\0MyApp\0\0");

//Verify hdcMeta is good
TextOut(hdcMeta, 0, 0, "Draft", 5);

//Fake out the app to draw to our DC
//Since hWnd is in another thread, we
//need to use PostMessage
//Since we use PostMessage, we need to
//be sure that hWnd has time
//to process and print to m_hdcMeta

PostMessage(hWnd, WM_PRINT, (WPARAM)hdcMeta, PRF_OWNED);

Sleep(5000);
      
henMF = CloseEnhMetaFile(m_hdcMeta);

// Release the reference DC.
ReleaseDC(hWnd, hdcRef);
0
AndersonAdrian
Asked:
AndersonAdrian
  • 6
  • 2
1 Solution
 
NickRepinCommented:
Before use EMF, you have to close it first.

SDK says:

<<An application can use the enhanced-metafile handle returned by the CloseEnhMetaFile function to perform the following tasks:

Display a picture stored in an enhanced metafile >>
0
 
NickRepinCommented:
Sorry, I misunderstood your question.

1) You have to use SendMessage instead of PostMessage, because EMF may be closed before abother app receives your message. It is better than Sleep().
But it is not very important, because

2) HDC is only valid in the context of the YOUR application, and not in the context of another application. If I'm not wrong.

If another app is your app, then you have to pass the name of the metafile to another app so it can send WM_PAINT message to itself.

If another app is not written by you, there are several ways.
Easiest one is to install, say, WH_GETMESSAGE hook to another app's thread. Hook proc will be called in the address space of that another app, so inside this proc you can create the metafile and send WM_PRINT message to the app window.

0
 
NickRepinCommented:
Ask me if you need additional details.
0
Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

 
MichaelSCommented:
HDC valid not only in one app.
0
 
AndersonAdrianAuthor Commented:
-Sounds like I need to implement a WH_GETMESSAGE hook.  How do I do that?  
0
 
NickRepinCommented:
<<HDC valid not only in one app>>
Wrong


SetWindowsHookEx(WH_GETMESSAGE...)
0
 
AndersonAdrianAuthor Commented:
Thanks
0
 
NickRepinCommented:
Does it work?
0
 
NickRepinCommented:
It must be something like this:

Your_program.cpp:
-----------------

UINT msg1=RegisterWindowMessage("Your_program_get_metafile")

UINT msg2=RegisterWindowMessage("Your_program_metafile_created")

DWORD threadId=GetWindowThreadProcessId(
hWnd,0);

setHook(threadId);

// Post, not Send.
PostMessage(hWnd,msg1,...)

// Waiting for msg2 message. Once received, metafile can be used and the hook can be uninstalled.

unhook();



Hook.dll
--------

UINT msg1=RegisterWindowMessage("Your_program_get_metafile")

UINT msg2=RegisterWindowMessage("Your_program_metafile_created")

void setHook(DWORD threadId)
{
SetWindowsHookEx(WH_GETMESSAGE,...,threadId);
}

.... HookProc(.....)
{
  if(code>0) {
     LPMSG msg=(LPMSG)lParam;
     if(msg->message=msg1) {

           HDC dc=GetDC(msg->hwnd);
           // All your code here.
           ....
           // Send, not Post
           SendMessage(msg->hwnd,WM_PRINT,......);
           ...
           // Notify your app that the job is done
           // PostMessage(yourWindow,msg2,...)


     }

  }
  retrun CallNextHookEx(...)
}
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now