Solved

Printing : Using win32 (print to pdf file)

Posted on 2008-10-21
48
663 Views
Last Modified: 2013-11-26
I have to develop a dll application in visual studio .net 2003 to print any file to pdf file format.I am presently  using a unigraphics part file(or any other text file ) to print. With what code i have written that is when i execute a pdf file is being generated but it is empty, only a plain white sheet is present.I dont know where i am going wrong. I think there is some problem in input.I am using a printdlg function and im using GetActiveWindow() to get the handleof the present window and i am passing it in the structure.This function i am calling after UF_intialise
but if I try to create a new part in unigraphics(nx4) or after creating any simple sketch then call this handle is returning null value whereas after  UF_intialise it is not null. I am attaching my code below.I think it is not able to identify which page to print.

HDC GetPrinterDC(HWND hWndParent)

{

       PRINTDLG pdlg;

       // Initialize the PRINTDLG structure.

       memset( &pdlg, 0, sizeof( PRINTDLG ) );

       pdlg.lStructSize = sizeof( PRINTDLG );

 

      // Set the flag to return printer DC.

       pdlg.Flags = PD_RETURNDEFAULT | PD_RETURNDC;

 

       pdlg.hwndOwner = hWndParent;

 

      PrintDlg( &pdlg );

 

     // hDC member of the PRINTDLG structure contains the printer DC.

        return pdlg.hDC;

}

 

void InitDocStruct( DOCINFO* di, char* docname)

{

 

      // Always zero it before using it.

      memset( di, 0, sizeof( DOCINFO ) );

 

     // Fill in the required members.

     di->cbSize = sizeof( DOCINFO );

     di->lpszDocName = "test";        

}

 

BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )

{

            hInstance = (HINSTANCE)hModule;

            return TRUE;

}

 

extern "C" DllExport void ufusr( char *parm, int *returnCode, int rlen )

{

       int nErr = 0;

       HWND  hWnd = NULL;

       HDC        hDC;

       DOCINFO    di;

 

       nErr = UF_initialize();

       if (nErr != 0)

       {

           uc1601 ("Failed to initialise UG session", 1);

           return;

       }

       hWnd = GetActiveWindow();

       if (hWnd != NULL)

       {

             hDC = GetPrinterDC(hWnd);

             if( !hDC)

             {

 

                MessageBox(NULL, "Error creating DC", "Error",

                           MB_APPLMODAL | MB_OK );

             }

             InitDocStruct( &di, "Test");

 

            StartDoc( hDC, &di );

 

            StartPage( hDC );

 

            EndPage( hDC );

 

            EndDoc( hDC );

 

           DeleteDC( hDC );

      }

      nErr = UF_terminate();

Open in new window

0
Comment
Question by:Sohela
  • 26
  • 15
  • 7
48 Comments
 
LVL 49

Expert Comment

by:DanRollins
ID: 22774992
Your code does not do any output.  
After the StartPage call, you need to draw to the HDC.  For instance, add this line right after StartPage:
    TextOut(hDc, 300, 300, "here is a long line of text", 26 );
0
 

Author Comment

by:Sohela
ID: 22775049
Thanks for the reply but i want to print the whole page what is displayed on my screen not a line , like not what i give  manually how we do we go to File->Print->Pdf then the whole page is printed so i want like that which window is open how do we give input as that page.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22775591
>>>> but i want to print the whole page what is displayed on my screen not a line , l

Then you have to get your screen as bitmap and call StretchBlt to copy the bits to the printer HDC.

Note, you would get better results in the PDF if you would individually draw all elements (text, lines, images) of the page to the printer, cause by copying from the screen you'll get a very bad resolution (compared to printer) what especially would be seen with text output.
0
 

Author Comment

by:Sohela
ID: 22775658
Thanks for your reply but how do we know how much of the screen is to be captured through the code and i dont know what function or code is to be used  to get screen as bitmap.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 22780237
>>>> but i want to print the whole page what is displayed on my screen not a line
Uh....  Duh.
The code I provided was to demonstrate the important flaw in your posted program.  Do as I suggested to verify that doing some output at that point will indeed create a PDF that is not a blank page.
 Then we can move on to the next step.
0
 

Author Comment

by:Sohela
ID: 22783183
I am sorry i didnt mean it like that i thought you didnt get my question correctly so i wrote that. I have included that TextOut function but the pdf document is still blank i used the GetLastError () function and there is a error in the StartDoc () function which is returning 13 that is The data is invalid. I dont know where is the error and even the docname is not coming as the filename.Thanks for your reply.
0
 

Author Comment

by:Sohela
ID: 22783360
I have changed some values in the textout function and the line is getting printed but after the function is executed it is still showing  the same error i.e the data is invalid.
TextOut(hDC, 0,0, "Test Printing", lstrlen( "Test Printing" );
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22783440
>>>> lstrlen( "Test Printing" );
it either should be

       strlen( "Test Printing" );

or

     wcslen(L"Test Printing" );
0
 

Author Comment

by:Sohela
ID: 22783495
Ok to print the page as you mentioned i am trying to use BitBlt function but i dont know which functions i am supposed to use or where to like for using BitBlt  function i need to do CreateDC (), CreateCompatibleDC, CreateCompatibleBitmap () functions so i still need to use PrintDlg () ,InitDocStruct,(), StartDoc(), StartPage () or i need to skip anything i dont understand it. i dont know what changes should i make in the above code to include the code given below and where to fit this.Thanks.
HDC hdcScreen; 

	hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL); 

	d = GetLastError();
 

	HDC hdcCompatible;

	hdcCompatible = CreateCompatibleDC(hdcScreen); 

	d = GetLastError();
 

	HBITMAP hbmScreen;

	hbmScreen = CreateCompatibleBitmap(hdcScreen, 

									   GetDeviceCaps(hdcScreen, HORZRES), 

									   GetDeviceCaps(hdcScreen, VERTRES));

	d = GetLastError();
 

	HGDIOBJ  selObj;

	selObj = SelectObject(hdcCompatible, hbmScreen);

	d = GetLastError();
 

	BOOL shWin;

	shWin = ShowWindow(hWnd, SW_SHOW); 

	d = GetLastError();
 

	BOOL bit;

	bit = BitBlt(hdcCompatible, 0, 0, 10,10, 

			hdcScreen, 0, 0, SRCCOPY); 

	d = GetLastError();

Open in new window

0
 
LVL 49

Expert Comment

by:DanRollins
ID: 22783836
The value returned from StartDoc (13) is the "print job ID" -- it is not an error code.  See:
    StartDoc
    http://msdn.microsoft.com/en-us/library/ms535793(VS.85).aspx
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22784862
>>>> i am trying to use BitBlt function
Ok the BitBlt copied the screen contents to the compatible device context. But you woull need to copy it to the printer HDC. Use the StretchBlt for that as you have different dimensions (and you might have to rotate the bits).
0
 

Author Comment

by:Sohela
ID: 22784902
>>>>.Use the StretchBlt for that as you have different dimensions (and you might have to rotate the bits).
I have mad esome changes in the code the ooutput of this is like when we give print screen manually.I dont know what to give to get only the screen not the total with menu bars and title bars.I think i have to make changes in GetMetricSystem() arguments but what to make i am unable to understand.Thanks.
void PrintScreen (HWND hWnd)

{

	HDC hScreenDC;
 

	if ((hScreenDC = GetDC (hWnd)) != NULL) {

		HDC hMemDC;
 

		if ((hMemDC = CreateCompatibleDC (hScreenDC)) != NULL) {

			HBITMAP hFullScreenBitmap;
 

			int iScreenWidth  = GetSystemMetrics (SM_CXFULLSCREEN

);		   

		int iScreenHeight = GetSystemMetrics (SM_CYFULLSCREEN);		   

			

			if ((hFullScreenBitmap = CreateCompatibleBitmap (hScreenDC, iScreenWidth, iScreenHeight)) != NULL) {

				HBITMAP hDefaultBitmap = (HBITMAP) SelectObject (hMemDC, hFullScreenBitmap);
 

				// From screen to memory:

				BitBlt (hMemDC, 0, 0, iScreenWidth, iScreenHeight, hScreenDC, 0, 0, SRCCOPY);

				SelectObject (hMemDC, hDefaultBitmap);

				SelectObject (hMemDC, hFullScreenBitmap);
 

				// Printing:

				PRINTDLG pd = {0}; // Reset on declare
 

				pd.lStructSize = sizeof (pd);

				pd.Flags = PD_RETURNDEFAULT | PD_ALLPAGES | PD_RETURNDC;

				pd.nFromPage = 1;

				pd.nToPage =  1;

				pd.nCopies = 1;
 

				if (PrintDlg (&pd)) {

					if (pd.hDC) {

						// Scaling to fit on a printer page:

						double dblScreenRatio = (double) iScreenWidth / (double) iScreenHeight;

						int xPrnPixelsPerPage = GetDeviceCaps (pd.hDC, PHYSICALWIDTH);

						int xPrnPixelsMargin = GetDeviceCaps (pd.hDC, PHYSICALOFFSETX);

						int yPrnPixelsMargin = GetDeviceCaps (pd.hDC, PHYSICALOFFSETY);

						int printedWidth = xPrnPixelsPerPage - xPrnPixelsMargin * 2;

						int printedHeight = (int) ((double) printedWidth / dblScreenRatio);
 

						DOCINFO di = {0};
 

						di.cbSize = sizeof (di);

						di.lpszDocName = "Print Full Screen";
 

						StartDoc (pd.hDC, &di);

						StartPage (pd.hDC);
 

						// FINALLY!

						StretchBlt (pd.hDC,

									xPrnPixelsMargin, yPrnPixelsMargin, printedWidth, printedHeight,

									hMemDC, 0, 0, iScreenWidth, iScreenHeight, SRCCOPY);
 

						EndPage (pd.hDC);

						EndDoc (pd.hDC);

						DeleteDC (pd.hDC);

					}

					// Clean up after print dlg:

					if (pd.hDevMode) {

						GlobalFree (pd.hDevMode);

					}

					if (pd.hDevNames) {

						GlobalFree (pd.hDevNames);

					}

				}

				SelectObject (hMemDC, hDefaultBitmap);

				DeleteObject (hFullScreenBitmap);

			}

			DeleteDC (hMemDC);

		}

		ReleaseDC (NULL, hScreenDC);

	}

}

Open in new window

0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22785896
>>>> what to give to get only the screen not the total
You need to call GetWindowRect for the window/frame you want to print.

Then supply these coordinates to the BitBlt where you do the SRC_COPY

   RECT rect = { 0 };
   GetWindowRect(hwndFrame, &rect);
   BitBlt (hMemDC, 0, 0, rect.right-rect.left,  rect.bottom-rect.top, hScreenDC, rect.left, rect.top, SRCCOPY);
0
 

Author Comment

by:Sohela
ID: 22793409
>>>>>>..You need to call GetWindowRect for the window/frame you want to print.
 RECT rect = { 0 };
   GetWindowRect(hwndFrame, &rect);
   BitBlt (hMemDC, 0, 0, rect.right-rect.left,  rect.bottom-rect.top, hScreenDC, rect.left, rect.top, SRCCOPY);
Ater using this also i am getting the same whole screen is getting printed not with title bars ,menu bars and all.I dont know where more should i make changes.



0
 
LVL 49

Expert Comment

by:DanRollins
ID: 22794240
Usw GetClientRect(), as I described in your other question.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22794277
>>>> the same whole screen is getting printed not with title bars ,

What is the hwndFrame (what window) ? And what are the coordinates you got back when calling GetWindowRect?

>>>> I dont know where more should i make changes

I would have a few ideas. You first could try to describe more thoroughly what you have done and waht were the results. I actually don't know whether you had any printouts til yet or whether you still were grabbing bitmaps from your screen.

>>>> Usw GetClientRect(), as I described in your other question.
GetClientRect returns a rectangle with top-left = (0, 0). I can't see why it should give better results when using it in a (source-)copying from screen to bitmap.
0
 

Author Comment

by:Sohela
ID: 22794423
>>>>>>>>>>What is the hwndFrame (what window) ? And what are the coordinates you got back hwndFrame i am passing the handle of the window which i have to print to pdf format.

>>>>>>>>>when calling GetWindowRect?
When i am calling GetWindowRect i am getting values
rect.right= 1280,
rect.left = 0,
rect.bottom = 904,
rect.top = 0,

>>>>>>I actually don't know whether you had any printouts til yet or whether you still were grabbing bitmaps from your screen.
Like i didnt understand what you meant by this i am trying to print to pdf file that is i give print option in the name of printer i select pdf complete.The changes what you told i made but it is still the same .I am attaching the code should i skip any thig from the code or replace anything .I have tried using GetClientRect() also it is giving the same output.
void PrintScreen (HWND hWnd)

{

	HDC hScreenDC;

 

	if ((hScreenDC = GetDC (hWnd)) != NULL) {

		HDC hMemDC;

 

		if ((hMemDC = CreateCompatibleDC (hScreenDC)) != NULL) {

			HBITMAP hFullScreenBitmap;

 

			int iScreenWidth  = GetSystemMetrics (SM_CXFULLSCREEN);		   

		    int iScreenHeight = GetSystemMetrics (SM_CYFULLSCREEN);

			

			 RECT rect = { 0 };

			 GetWindowRect(hwndFrame, &rect);

  

			if ((hFullScreenBitmap = CreateCompatibleBitmap (hScreenDC, iScreenWidth, iScreenHeight)) != NULL) {

				HBITMAP hDefaultBitmap = (HBITMAP) SelectObject (hMemDC, hFullScreenBitmap);

 

				// From screen to memory:

				 BitBlt (hMemDC, 0, 0, rect.right-rect.left,  rect.bottom-rect.top, hScreenDC, rect.left, rect.top, SRCCOPY);

				SelectObject (hMemDC, hDefaultBitmap);

				SelectObject (hMemDC, hFullScreenBitmap);

 

				// Printing:

				PRINTDLG pd = {0}; // Reset on declare

 

				pd.lStructSize = sizeof (pd);

				pd.Flags = PD_RETURNDEFAULT | PD_ALLPAGES | PD_RETURNDC;

				pd.nFromPage = 1;

				pd.nToPage =  1;

				pd.nCopies = 1;

 

				if (PrintDlg (&pd)) {

					if (pd.hDC) {

						// Scaling to fit on a printer page:

						double dblScreenRatio = (double) iScreenWidth / (double) iScreenHeight;

						int xPrnPixelsPerPage = GetDeviceCaps (pd.hDC, PHYSICALWIDTH);

						int xPrnPixelsMargin = GetDeviceCaps (pd.hDC, PHYSICALOFFSETX);

						int yPrnPixelsMargin = GetDeviceCaps (pd.hDC, PHYSICALOFFSETY);

						int printedWidth = xPrnPixelsPerPage - xPrnPixelsMargin * 2;

						int printedHeight = (int) ((double) printedWidth / dblScreenRatio);

 

						DOCINFO di = {0};

 

						di.cbSize = sizeof (di);

						di.lpszDocName = "Print Full Screen";

 

						StartDoc (pd.hDC, &di);

						StartPage (pd.hDC);

 

						// FINALLY!

						StretchBlt (pd.hDC,

									xPrnPixelsMargin, yPrnPixelsMargin, printedWidth, printedHeight,

									hMemDC, 0, 0, iScreenWidth, iScreenHeight, SRCCOPY);

 

						EndPage (pd.hDC);

						EndDoc (pd.hDC);

						DeleteDC (pd.hDC);

					}

					// Clean up after print dlg:

					if (pd.hDevMode) {

						GlobalFree (pd.hDevMode);

					}

					if (pd.hDevNames) {

						GlobalFree (pd.hDevNames);

					}

				}

				SelectObject (hMemDC, hDefaultBitmap);

				DeleteObject (hFullScreenBitmap);

			}

			DeleteDC (hMemDC);

		}

		ReleaseDC (NULL, hScreenDC);

	}

}

Open in new window

hg.pdf
ghhg.pdf
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22794593
>>>> rect.left = 0
>>>> rect.top = 0,
It is the wrong window frame. You were taking mainframe window which is maximum sized on screen. Instead you should use the client window which should be a view or dialog window.

>>>> Like i didnt understand what you meant by this
I ask whether you already got a pdf printout or not?
0
 

Author Comment

by:Sohela
ID: 22794645
>>>> rect.left = 0
>>>> rect.top = 0,
It is the wrong window frame. You were taking mainframe window which is maximum sized on screen. Instead you should use the client window which should be a view or dialog window.

I have used even that but still i am getting the same output and like if i use either GetWindowRect  () and GetClientRect () the values what they are coming im storing it in iScreenHeight and iScreenWidth and these both i am using in various places in my code so should these values be in BitBlt function or everywhere i should use them as rect.right-rect.left,  rect.bottom-rect.top as you mentioned.

>>>>I ask whether you already got a pdf printout or not?
I attached two pdf files in the above post one is the pdf i am getting using code the other pdf i am getting when i do it manually there is a lot of variation. Would you please see them once.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22794859
>>>> I have used even that but still i am getting the same output
You need a window (handle) which has a top.left and top.right different to 0 cause point (0,0) is the top-left of the screen. GetClientRec always is wrong cause top-left is always (0,0) cause client coordinates are relative coordinates to the window itself.

>>>> Would you please see them once.
I was in a environment where I couldn't open attachments because of security reasons. I could look at them now and the second wasn't so bad, right?

>>>> the other pdf i am getting when i do it manually

In order to not have to do it manually, you need to identify the client window of your frame window. It should be the same hwnd which you use for drawing the shapes. If you call GetWindowRect for that you must get a top-left point different to (0,0).

0
 

Author Comment

by:Sohela
ID: 22794911
>>>>>>>>>>>I was in a environment where I couldn't open attachments because of security reasons. I could look at them now and the second wasn't so bad, right?

Actually the first pdf is the one which i am getting through code and the output should be like the one i showed in the second pdf file(the second pdf file i generated it manually) so i am supposed to get output like the second one whereas i am getting like the first one.

>>>>>>>. If you call GetWindowRect for that you must get a top-left point different to (0,0).
I am calling GetWindowRect but still i am getting (0, 0) how do i get other value for that.

>>>>>>>You need a window (handle) which has a top.left and top.right different to 0 cause point (0,0) is the top-left of the screen. GetClientRec always is wrong cause top-left is always (0,0) cause client coordinates are relative coordinates to the window itself.


And about the handle i am using GetActiveWindow()
i.e  hWnd = GetActiveWindow(); and i am passing this handle other than this i dont have any handles.I am sorry because it is taking a lot of your time but this is my first application in win32 thats why i am having so many problems.Thanks.

>>>>>>It is the wrong window frame. You were taking mainframe window which is maximum sized on screen. Instead you should use the client window which should be a view or dialog window.

How do we get view or dialog window.

0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22795100
>>>> I am calling GetWindowRect but still i am getting (0, 0) how do i get other value for that.

The window you were taking is the mainframe window. You need the client window of that which you could get by GetWindow(hwndFrame, GW_CHILD);

You also could try to save the client window when drawing the shapes into some global variable. That way you easoier could decide what is th right window cause the mainframe might have multiple child windows.
0
 

Author Comment

by:Sohela
ID: 22795281
>>>>>>>>GetWindow(hwndFrame, GW_CHILD);
I have used the above function in my code that i passed the handle from which we get from GetActiveWindow() to GetWindow() and inturn that handle to GetWindowRect function but i am not getting the required output.The output which i am getting from code is attatched to file i.e latest.pdfand ther equired output is OutRequired.pdf which i have atached below.Thanks.
	

{

	hWnd = GetActiveWindow();

	DWORD d = GetLastError();
 

	HWND hChild				= NULL;

	hChild = GetWindow(hWnd, GW_CHILD); 

	d = GetLastError();
 

	PrintScreen (hChild);

}
 

void PrintScreen (HWND hWnd)

{

	HDC hScreenDC;
 

	if ((hScreenDC = GetDC (hWnd)) != NULL) {

		HDC hMemDC;
 

		if ((hMemDC = CreateCompatibleDC (hScreenDC)) != NULL) {

			HBITMAP hFullScreenBitmap;
 

			RECT rect = { 0 };

			GetWindowRect(hWnd, &rect);
 

			int iScreenWidth = GetSystemMetrics (SM_CXFULLSCREEN);

			int iScreenHeight = GetSystemMetrics (SM_CYFULLSCREEN); 

					

			

			if ((hFullScreenBitmap = CreateCompatibleBitmap (hScreenDC, iScreenWidth, iScreenHeight)) != NULL)

			{

				HBITMAP hDefaultBitmap = (HBITMAP) SelectObject (hMemDC, hFullScreenBitmap);
 

				// From screen to memory:

			    BitBlt (hMemDC, 0, 0, rect.right-rect.left,  rect.bottom-rect.top, hScreenDC, rect.left, rect.top, SRCCOPY);
 

				SelectObject (hMemDC, hDefaultBitmap);

				SelectObject (hMemDC, hFullScreenBitmap);
 

				// Printing:

				PRINTDLG pd = {0}; // Reset on declare
 

				pd.lStructSize = sizeof (pd);

				pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC;  // PD_RETURNDEFAULT | PD_ALLPAGES | PD_RETURNDC;

				pd.nFromPage = 1;

				pd.nToPage = 1;

				pd.nCopies = 1;
 

				if (PrintDlg (&pd)) 

				{

					if (pd.hDC)

					{

						// Scaling to fit on a printer page:

						double dblScreenRatio = (double) iScreenWidth / (double) iScreenHeight;

						int xPrnPixelsPerPage = GetDeviceCaps (pd.hDC, PHYSICALWIDTH);

						int xPrnPixelsMargin = GetDeviceCaps (pd.hDC, PHYSICALOFFSETX);

						int yPrnPixelsMargin = GetDeviceCaps (pd.hDC, PHYSICALOFFSETY);

						int printedWidth = xPrnPixelsPerPage - xPrnPixelsMargin * 2;

						int printedHeight = (int) ((double) printedWidth / dblScreenRatio);
 

						DOCINFO di = {0};
 

						di.cbSize = sizeof (di);

						di.lpszDocName = "Print123";

											

						StartDoc (pd.hDC, &di);

						StartPage (pd.hDC);
 

						StretchBlt (pd.hDC, xPrnPixelsMargin, yPrnPixelsMargin, printedWidth, printedHeight,

									hMemDC, 0, 0, iScreenWidth, iScreenHeight, SRCCOPY);

						EndPage (pd.hDC);

						EndDoc (pd.hDC);

						DeleteDC (pd.hDC);

					}
 

					// Clean up after print dlg:

					if (pd.hDevMode) {

						GlobalFree (pd.hDevMode);

					}

					if (pd.hDevNames) {

						GlobalFree (pd.hDevNames);

					}

				}

				SelectObject (hMemDC, hDefaultBitmap);

				DeleteObject (hFullScreenBitmap);

			}

			DeleteDC (hMemDC);

		}

		ReleaseDC (NULL, hScreenDC);

	}

}

Open in new window

latest.pdf
OutRequired.pdf
0
 

Author Comment

by:Sohela
ID: 22795300
>>>>>>>GetWindow(hwndFrame, GW_CHILD);
Also now i am getting some values in rect.left and rect.top instead of 0 which i was getting previously.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22795411
>>>> hChild = GetWindow(hWnd, GW_CHILD);
The problem with this is that it only gets the first child window which probably is one of the toolbar buttons or the menu window.

You would need to iterate by calling

   hNextChild = GetWindow(hWnd, GW_HWNDNEXT);

in a loop until you finally got the client window. It would be much easier if you would check how the whole thing was created. Framewindow, menus, toolbar buttuns and finally the client window which is the window where you made your drawings of the rectangles and lines.

You definitively would get a windows handle back when that window was created. Store this handle to a global variable which you define at the top of your source file below include statements:

#include <windows.h>

HWND hwndClient = NULL;

.....
// somewhere in your code the client window was created ...

       hwnd = CreateWindow(....
       // store the hwnd for later use
       hwndClient = hwnd;


// and later you may use

     if (hwndClient != NULL)
     {
           PrintScreen(hwndClient);      
     }


The problem with the GW_CHILD approach could be that the client window wasn't a direct child from frame window but a 'grand' child. You really better save it at creating time cause that is much easier.



0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22795465
>>>> hFullScreenBitmap = CreateCompatibleBitmap (hScreenDC, iScreenWidth, iScreenHeight))
don't create the bitmap using screen sizes but only sizes of the rectangle .

     hFullScreenBitmap = CreateCompatibleBitmap (hScreenDC, rect.right-rect.left, rect.bottom-rect.top);
0
 

Author Comment

by:Sohela
ID: 22798026
>>>> if (hwndClient != NULL)
     {
           PrintScreen(hwndClient);      
     }
.Why do we have to use this code as you mentioned without using this previously it was printing no in my code (Im just asking as to why we have to use this anything specific).

>>>>>You really better save it at creating time cause that is much easier
How can we save this at the time of creating.

>>>>>don't create the bitmap using screen sizes but only sizes of the rectangle .
>>>>> hFullScreenBitmap = CreateCompatibleBitmap (hScreenDC, rect.right-rect.left, rect.bottom-rect.top);

I am using  iScreenWidth and iScreenHeight in four places for all the places shoul i replace it with   rect.right-rect.left,  rect.bottom-rect.top values .
hFullScreenBitmap = CreateCompatibleBitmap (hScreenDC, iScreenWidth, iScreenHeight)

BitBlt (hMemDC, 0, 0, iScreenWidth, iScreenHeight, hScreenDC, 0, 0, SRCCOPY);

double dblScreenRatio = (double) iScreenWidth / (double) iScreenHeight;

StretchBlt (pd.hDC, xPrnPixelsMargin, yPrnPixelsMargin, printedWidth, printedHeight,
             hMemDC, 0, 0, iScreenWidth, iScreenHeight, SRCCOPY);

From my code should i remove anything or comment out some step which is not necessary since you have mentioned me to add PrintScreen function. Where can i place this function after which step.

Thanks a lot.


0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22798674
>>>> How can we save this at the time of creating
Check your sources for CreateWindow. One of these must be the window we are looking for. You might see some comments. But actually I don't expect that you have more than 2 or 3 windows created (but I might be wrong with that).

>>>> Why do we have to use this code as you mentioned ...

I only used the code you posted and tried to show you how to take the correct window ...

When I told you to have

   GetWindowRect(hwndFrame, &rect);

I assumed that your application has multiple frame windows where one is that you wanted to print.

But obviously I was wrong with that - as I saw from your total screen image.

>>>> I am using  iScreenWidth and iScreenHeight in four places ...
>>>> shoul i replace it with   rect.right-rect.left,  rect.bottom-rect.top values .


Yes. As you want to print only a partial screen you might not use full screen sizes. For the output things might be different. You could increase  the sizes up to the sizes of the print device (but not changing the ratio between width and height).
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 22800030
Another way to find the target window is to use Spy++ (availube under the Visual Studios Tools menu)
Use its Find Window feature --- just move the mouse around until the inner window has a highlighting border, then check that window's properties. The classname or other attribute might provide enough identifying information so that you can use Win API funtctions such as GetWindow to focus in on the child window you want.
=-=-=-=
Going back to the original question -- you want to be able to "print any file to PDF."
Well, the route we are going will only allow you to print the visible content of a specific window. It does not generalize at all. If part of the data is "below the bottom" of the window, then it will not be printed.
I just thought we should clarify that now. If you want to make screen dumps to PDFs, then we are on the right track. If you want to print "any file" then we are not.
0
 

Author Comment

by:Sohela
ID: 22801167
>>>>>>>>I just thought we should clarify that now. If you want to make screen dumps to PDFs, then we are on the right track. If you want to print "any file" then we are not.

I want print to pdf file i dont want screen dumps and about the print any file i meant that it can a text file or a cad part file all these files content  should be printed to pdf file.At present what i am getting output is like when we do print screen because for the same file the output is different when we do it manualy(without code for checking).I have shown files in the above posts output.pdf is that which i am getting presently through code and OutRequired.pdf is the format in which i want the output to get printed.
0
 

Author Comment

by:Sohela
ID: 22801188
>>>>>When I told you to have
>>>>>  GetWindowRect(hwndFrame, &rect);
>>>>I assumed that your application has multiple frame windows where one is that you wanted to print.
>>>>>But obviously I was wrong with that - as I saw from your total screen image.

Then what should i do now should i change the code now.
0
 

Author Comment

by:Sohela
ID: 22801198
I mentioned about my output which i am getting through code it is you can refer to latest.pdf or hg.pdf i mentioned it as output.pdf by mistake inj my above post.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22802151
>>>> Then what should i do now should i change the code now.
You already did some changes that were good but we still have problems to get the right window and you were still using wrong sizes and rectangles.

1. Find the client window

Did you check your code for calls of CreateWindow?
 
If yes, did any of these calls look like the creation of a client window?
     Did you save the hwnd returned from that CreateWindow then into a global variable for later use?  

If no, did you find the function where the drawing of the construction image was made?
     Did you save the hwnd used in that drwaing function into a global variable for later use?

if again no, did you loop thru all child windows of the hwndFrame by calling hwnd = GetWindow(hwnd, GW_CHILD)  and hwnd = GetWindow(hwnd, GW_HWNDNEXT) and check all rectangles of these child windows if one of them could be the client window?

If you don't find the client window (hwnd) by neither way you could calculate the client window rectangle by taking rectangle of hwndFrame and add/subtract the sizes for title, menu, lines until you reached the left-top of the client area. The sizes for those elements you would get by GetSystemMetrics.

2. Use the correct sizes for BitBlt and StretchBlt.

The first BitBlt where you were grabbing picture from screen *MUST* have 0, 0 for the target (bitmap) origin, must have the width and height of the client area to grab, must have the left-top of the client area in windows coordinates in order to grab the total client area but nothing else.

For all further BitBlt or StretchBlt you might take the same sizes and always (0, 0) as top-left as well for target and source cause if you already picked only the image to print you may not make this image smaller (as it looked in your latest.pdf) by using an offset in the top-left of the source to copy.

Finally, if your image has not the correct output size in the pdf (I assume it will be smaller), you may increase the sizes of output image by increasing the output sizes in StretchBlt (but not changing the ratio).

     
0
 

Author Comment

by:Sohela
ID: 22803857
At present i cannot check the code because i am not at work place is it ok if i cannot check the code now.It may take another two days before i check the code again is it fine with you or should i accept the solution and give you points.Please reply.Thanks
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22806845
>>>> It may take another two days before i check the code
That is ok. You may not close the question if there is still something open.

0
 

Author Comment

by:Sohela
ID: 22807928
>>>>>>>>That is ok. You may not close the question if there is still something open.
Thanks a lot
0
 

Author Comment

by:Sohela
ID: 22828683
hiiii,
>>> hwndFrame by calling hwnd = GetWindow(hwnd, GW_CHILD)  and hwnd = GetWindow(hwnd, GW_HWNDNEXT) and check all rectangles of these child windows if one of them could be the client window?

i have done the above step what you specified but still i am getting the same result

>>>>.If you don't find the client window (hwnd) by neither way you could calculate the client window rectangle by taking rectangle of hwndFrame and add/subtract the sizes for title, menu, lines until you reached the left-top of the client area. The sizes for those elements you would get by GetSystemMetrics.

I am using GetSystemMetrics (SM_CXBORDER) or what argument should i pass in GetSystemMetrics function to get the size of the menu.Thanks
0
 

Author Comment

by:Sohela
ID: 22828767
Here when i do hNextChild = GetWindow(hWnd, GW_HWNDNEXT); and pass hNextChild in GetWindowRect(hNextChild , &rect); instead of GetWindowRect(hWnd, &rect); i am getting output as balckscreen.Maybe i am not doing it correctly.


	HWND hChild				= NULL;

	hChild = GetWindow(hWnd, GW_CHILD); 

	d = GetLastError();
 

	HWND hNextChild				= NULL;

	hNextChild = GetWindow(hWnd, GW_HWNDNEXT); 

	d = GetLastError();
 

	PrintScreen (hWnd, hNextChild);
 

void PrintScreen (HWND hWnd, HWND hChild)

{

     HDC hScreenDC;

     if ((hScreenDC = GetDC (hWnd)) != NULL) {

     HDC hMemDC;
 

    if ((hMemDC = CreateCompatibleDC (hScreenDC))!=NULL) 

    {

	HBITMAP hFullScreenBitmap;

         RECT rect = { 0 };

         GetWindowRect(hWnd, &rect);
 

         int iScreenWidth = GetSystemMetricsSM_CXFULLSCREEN);

	int iScreenHeight = GetSystemMetrics (SM_CYFULLSCREEN); 
 

         if ((hFullScreenBitmap = CreateCompatibleBitmap (hScreenDC,   

                                                         rect.right-                                                         rect.left, 

                                                         rect.bottom-                                                         rect.top)) != 

                                                         NULL)

        {

	  HBITMAP hDefaultBitmap = (HBITMAP) SelectObject (hMemDC, 

                                                 hFullScreenBitmap);
 

	// From screen to memory:

	BitBlt (hMemDC, 0, 0, rect.right-rect.left, rect.bottom- 

                 rect.top, hScreenDC, rect.left, rect.top, SRCCOPY);
 

	SelectObject (hMemDC, hDefaultBitmap);

	SelectObject (hMemDC, hFullScreenBitmap);
 

	// Printing:

	PRINTDLG pd = {0}; // Reset on declare
 

	pd.lStructSize = sizeof (pd);

         pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC;  		pd.nFromPage = 1;

	pd.nToPage = 1;

	pd.nCopies = 1;
 

	if (PrintDlg (&pd)) 

	{

	    if (pd.hDC)

	    {

	       // Scaling to fit on a printer page:

	      double dblScreenRatio = (double) iScreenWidth /    

                                       (double) iScreenHeight;

						

              int xPrnPixelsPerPage = GetDeviceCaps (pd.hDC, 

                                      PHYSICALWIDTH);

						

             int xPrnPixelsMargin = GetDeviceCaps (pd.hDC, 

                                      PHYSICALOFFSETX);

						

             int yPrnPixelsMargin = GetDeviceCaps (pd.hDC, 

                                    PHYSICALOFFSETY);

						

            int printedWidth = xPrnPixelsPerPage - xPrnPixelsMargin * 2;

						

            int printedHeight = (int) ((double) printedWidth /        

                                 dblScreenRatio);
 

	  DOCINFO di = {0};
 

	 di.cbSize = sizeof (di);

	 di.lpszDocName = "Print123";

								StartDoc (pd.hDC, &di);

	StartPage (pd.hDC);
 

	StretchBlt (pd.hDC, xPrnPixelsMargin, yPrnPixelsMargin, 

                     printedWidth, printedHeight,hMemDC, 0, 0, 

                     iScreenWidth, iScreenHeight, SRCCOPY);
 

	EndPage (pd.hDC);

	EndDoc (pd.hDC);

	DeleteDC (pd.hDC);

     }

    // Clean up after print dlg:

    if (pd.hDevMode) {GlobalFree (pd.hDevMode);}

    if (pd.hDevNames) {GlobalFree (pd.hDevNames);}

  }

  SelectObject (hMemDC, hDefaultBitmap);

  DeleteObject (hFullScreenBitmap);

 }

 DeleteDC (hMemDC);

}

ReleaseDC (NULL, hScreenDC);

}

}

Open in new window

0
 

Author Comment

by:Sohela
ID: 22828869
>>>>>>>>>The problem with this is that it only gets the first child window which probably is one of the toolbar buttons or the menu window.

You would need to iterate by calling

   hNextChild = GetWindow(hWnd, GW_HWNDNEXT);

in a loop until you finally got the client window.
I am iterating this value hNextChild = GetWindow(hWnd, GW_HWNDNEXT); but i am getting the same valuee in the handle.

>>>>> It would be much easier if you would check how the whole thing was created. Framewindow, menus, toolbar buttuns and finally the client window which is the window where you made your drawings of the rectangles and lines.

How can we check how was the whole thing created like which window it is



0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 500 total points
ID: 22829019
>>>> I am iterating this value hNextChild = GetWindow(hWnd, GW_HWNDNEXT); but i am getting the same valuee in the handle.

The hWnd argument need to be changed with each iteration:

          HWND hwndNext = GetWindow(hWnd, GW_FIRSTCHILD);
          while (hwndNext != NULL)
          {
                RECT rect = { 0 };
                GetWindowRect(hwndNext, &rect);
                // check here the rectangle whether it could be the client rect you were looking for


                // next iteration
                hwndNext = GetWindow(hwndNext , GW_HWNDNEXT);

          }
0
 

Author Comment

by:Sohela
ID: 22829230
>>>>>>The hWnd argument need to be changed with each iteration:

          HWND hwndNext = GetWindow(hWnd, GW_FIRSTCHILD);
          while (hwndNext != NULL)
          {
                RECT rect = { 0 };
                GetWindowRect(hwndNext, &rect);
                // check here the rectangle whether it could be the client rect you were looking for


                // next iteration
                hwndNext = GetWindow(hwndNext , GW_HWNDNEXT);

          }

I have implemented the code and i was debugging it iterated 11 times how should i know over here which is the correct window. Each time i notd the values of rect.left, rect.right, rect.top, rect.bottom i checked for the first and last handle values i am adding the file for the first handle value.And whenever i am going into debug mode it is printing the code screen not my part screen whereas if i am executing it is taking the coorect screen can u try to tell me why this is happening.Here the output what i am getting and what i am supposed to get is different should i make anymore changes.Thanks.
latest-output.pdf
required-output.pdf
0
 

Author Closing Comment

by:Sohela
ID: 31508617
Thanks a lot for replying for the question i still have some doubts but thanks a lotttt.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22860615
>>>> it iterated 11 times how should i know over here which is the correct window.

You could call your PrintScreen for each of it (maybe by adding some kind of name or the rectangle coordinates).


>>>> it is printing the code screen not my part screen whereas if i am executing it is taking the coorect screen can u try to tell me why this is happening.
If you were grabbing from screen while the debugger is active you rarely have a chance to grab your application's screen but that what the screen shows to the time of grabbing ... beside you would grab the whole screen only once - before breaking into the debugger - and then take that 'hardcopy' as source for any further grab.

Could you post all calls to BitBlt, StretchBlt including how you determind the rectangles used for each of the calls?  
0
 

Author Comment

by:Sohela
ID: 22864631
hiii thanks for replying i checked  the rect values for each iteration and for the first iteration what values i was getting that only was giving correct screen but at the bottom it was giving the task bar so i subtracted some values from that.But there is still some difference like in the output file it is capturing screen and printing but when i do it without using code output is different right (i am attaching the files) only the lines are getting printed.Thanks.
    hWnd = GetActiveWindow();

	DWORD d = GetLastError();
 

	HWND hwndNext				= NULL;

	hwndNext = GetWindow(hWnd, GW_CHILD); 

	d = GetLastError();
 

	RECT rect = { 0 };

	GetWindowRect(hwndNext, &rect);
 

	PrintScreen (hWnd, hwndNext);
 

	void PrintScreen (HWND hWnd, HWND hChild)

	{

		HDC hScreenDC;

		char szmessage[133] = "";
 

		if ((hScreenDC = GetDC (hWnd)) != NULL) {

		HDC hMemDC;

		

		if ((hMemDC = CreateCompatibleDC (hScreenDC)) != NULL)

		{

			HBITMAP hFullScreenBitmap;
 

			int iScreenWidth = GetSystemMetrics (SM_CXFULLSCREEN);

			int iScreenHeight = GetSystemMetrics (SM_CYFULLSCREEN); 
 

			int nLeft, nTop, nWidth, nHeight;

			RECT rect = { 0 };

			RECT rect1 = { 0 };

			char szNewExp[1024]      = "\0";				// String value
 

			GetWindowRect(hChild, &rect);
 

			if ((hFullScreenBitmap = CreateCompatibleBitmap (hScreenDC, rect.right-rect.left, rect.bottom-rect.top)) != NULL)

			{

				HBITMAP hDefaultBitmap = (HBITMAP) SelectObject (hMemDC, hFullScreenBitmap);
 

				// From screen to memory:

				BitBlt (hMemDC, 0, 0, rect.right-rect.left, rect.bottom-rect.top, hScreenDC, rect.left, rect.top, SRCCOPY);

				SelectObject (hMemDC, hDefaultBitmap);

				SelectObject (hMemDC, hFullScreenBitmap);
 

				// Printing:

				PRINTDLG pd = {0};				//  Reset on declare
 

				pd.lStructSize = sizeof (pd);

				pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC;  // PD_RETURNDEFAULT | PD_ALLPAGES | PD_RETURNDC;

				pd.nFromPage = 1;

				pd.nToPage = 1;

				pd.nCopies = 1;
 

				if (PrintDlg (&pd)) 

				{

					if (pd.hDC)

					{

						// Scaling to fit on a printer page:

						double dblScreenRatio = (double) iScreenWidth / (double) iScreenHeight;

						int xPrnPixelsPerPage = GetDeviceCaps (pd.hDC, PHYSICALWIDTH);

						int xPrnPixelsMargin = GetDeviceCaps (pd.hDC, PHYSICALOFFSETX);

						int yPrnPixelsMargin = GetDeviceCaps (pd.hDC, PHYSICALOFFSETY);

						int printedWidth = xPrnPixelsPerPage - xPrnPixelsMargin * 2;

						int printedHeight = (int)((double) printedWidth / dblScreenRatio);
 

						DOCINFO di = {0};

						di.cbSize = sizeof (di);

						di.lpszDocName = "C:\\Printing.pdf";

															

						StartDoc (pd.hDC, &di);

						StartPage (pd.hDC);
 

						StretchBlt (pd.hDC, xPrnPixelsMargin, yPrnPixelsMargin, printedWidth, printedHeight,

									hMemDC, 0, 0, rect.right-rect.left, ((rect.bottom-rect.top)-27), SRCCOPY);
 

						EndPage (pd.hDC);

						EndDoc (pd.hDC);

						DeleteDC (pd.hDC);

					}
 

					// Clean up after print dlg:

					if (pd.hDevMode) {

						GlobalFree (pd.hDevMode);

					}

					if (pd.hDevNames) {

						GlobalFree (pd.hDevNames);

					}

				}

				SelectObject (hMemDC, hDefaultBitmap);

			

				DeleteObject (hFullScreenBitmap);

			}

			DeleteDC (hMemDC);

		}

		ReleaseDC (NULL, hScreenDC);

	}

}

Open in new window

required-output.pdf
Printing.pdf
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 22865579
This is what I told you before (see: http:#22800030)
You are now printing the screen.  What you really need to do is invoke the function of that program that will cause it to format and print the file.
0
 

Author Comment

by:Sohela
ID: 22866028
>>>   (see: http:#22800030)  Going back to the original question -- you want to be able to "print any file to PDF."
Well, the route we are going will only allow you to print the visible content of a specific window. It does not generalize at all. If part of the data is "below the bottom" of the window, then it will not be printed.

I just thought we should clarify that now. If you want to make screen dumps to PDFs, then we are on the right track. If you want to print "any file" then we are not.

Ya i need part of the data is "below the bottom" of the window also to be printed. how can we get it.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 22866153
As is stated quite clearly in http:#a22865579
What you really need to do is invoke the function of that program that will cause it [that program] to format and print the file.
0
 

Author Comment

by:Sohela
ID: 22866454
>>>>What you really need to do is invoke the function of that program that will cause it [that program] to format and print the file.

I dont think i can use spy++ and i am calling that function only can you tell me in the code like which one i am supposed to call.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
I. Introduction There's an interesting discussion going on now in an Experts Exchange Group — Attachments with no extension (http://www.experts-exchange.com/discussions/210281/Attachments-with-no-extension.html). This reminded me of questions tha…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now