|
I am trying to write a function for a CFormView called BatchPrintPage2().. the first part of this function is trying to get a handle on HDC. This is before I try to get the hDC:
DOCINFO di ;
CPrintInfo printInfo ;
CMyDoc *pDoc = (CMyDoc*)GetDocument() ;
CString filename ;
CDC dc ;
CRect draw_area ;
ASSERT_VALID(pDoc) ;
filename = pDoc->GetPathName() ; // make sure the compares will match
filename.MakeLower() ;
CPrintDialog dlg(FALSE) ;
at this point i try to get the hDC, the first way i was told to try was:
HDC hDC = dlg.CreatePrinterDC() ;
but this always returns null.
the other way i have tried is:
dlg.GetDefaults();
HDC hDC = dlg.m_pd.hDC;
this actually seems to work.. but then i get to the rest of the function..
di.cbSize = sizeof(DOCINFO) ;
di.lpszDocName = pDoc->GetPathName() ;
di.lpszOutput = filename ; // prepare the print information structure
dc.Attach(hDC) ;
printInfo.m_bDirect = TRUE ;
printInfo.m_rectDraw.left = 0 ;
printInfo.m_rectDraw.right = dc.GetDeviceCaps(HORZRES) ;
printInfo.m_rectDraw.top = 0 ;
printInfo.m_rectDraw.bottom = dc.GetDeviceCaps(VERTRES) ;
draw_area = printInfo.m_rectDraw ;
dc.StartDoc(&di) ;
OnPreparePrinting(&printInfo) ; // start printing the document
for (printInfo.m_nCurPage = 1 ; printInfo.m_nCurPage <= printInfo.GetMaxPage() ; printInfo.m_nCurPage++)
{
dc.StartPage() ;
OnPrint(&dc, &printInfo) ;
dc.EndPage() ; // reset page size as OnPrint may have modified them when header / footers were added to the page
printInfo.m_rectDraw = draw_area ;
}
OnEndPrinting(&dc, &printInfo) ;
dc.EndDoc() ;
VERIFY(dc.DeleteDC()) ;
this doesn't give any errors, but nothing prints. When tracing i see that OnDraw is called, but IsPrinting() is false. I have tried setting dc.m_bPrinting = TRUE, and this makes onDraw get called with IsPrinting() true, but it still prints nothing. My printer queue actually shows the job being sent to the printer, but when i captured the screen and look at it the 'Pages' and 'Size' columns are both blank..
also a major problem is that the 'for' loop listed above corrupts the hell out of my document.. my document file just gets destroyed with garbage from this for loop.. the dc.StartPage() sets the file to the following: (does this look like its printing to the document file somehow?)
%-12345X@PJL ENTER LANGUAGE=PCL600
*t600R&u600D*r3F&l0O&l1H&l2a8c1E*p0x0Y&l1X*b0M
*v0o0TE%-12345X
any help is much appreciated.. i can almost smell printing a bunch of views without a dialog
thanks!
-dz
|
|
|
|
|
Further to my reply in your other thread.
Looking at the code, if your getting a valid DC then I would expect this to work. The first things to check are that you are setting the number of pages you want to print in the views OnPreparePrinting function. For testing I would by default set this to 1.
pInfo->SetMaxPage(1) ;
You will then know exactly how many times the loop will run for. The next thing is to check for the document corruption that is happening. Put a breakpoint at the start of the for loop, and try stepping over the function in it while viewing the pDoc object in the variables/watch window. If you see any of them change (turn red), then you will see in what procedure the corruption of your doc object is happening. I would most probably think that its the CView::OnPrint() or CView::OnDraw() procedures at fault. As this code you are using is a derivative of code I used for printing documents to a PDF file (where I get a DC for a PDF printer driver), I would expect all that to work without problems.
I just noticed that there is a call to CView::OnBeginPrinting() missing just before the for loop, this is probably what will set the m_bPrinting falg for OnDraw to work correctly. It may also do some other miscellaneous stuff to avoid the corruption that is happening.
If you have further problems, post some updated code and we can go from there. It may also help to post the OnDraw() code of your view.
Roger Allen
Sonork 100.10016
If I had a quote, it would be a very good one.
|
|
|
|
|
woop!
the whole problem was the line:di.lpszOutput = filename; i set this equal to NULL and it actually printed all of my selected pages apparently the output was set to print to the file 'filename' which was set to my document name earlier in the code, it must be set to NULL to be 'sent to the device identified by the device context handle that was passed to the StartDoc function' (msdn).
now all i gotta do is figure out why my pages are 1/10th of the size they are when i print from the view with the print button heheh
thank you so much!
-dz
|
|
|
|
|
Since you are rolling your own printing, after you attach the printer DC to you CDC object you should do this:
dc.m_bPrinting = TRUE;
In case any of your drawing code is using pDC->IsPrinting(). I didn't see it in your example code.
Have fun.
Jonathan Craig
www.mcw-tech.com
|
|
|
|
|
Hello!
I'm trying to use a vector, but it seems like I'm not that clever.
How can I sort my vector<class> by one of the Class attributes, in my case ctDate?
typedef struct tagSCHEDULEBLOCK
{ CTime ctDate;
CString csText;
}SCHEDULEBLOCK;
vector<scheduleblock*> MyVector;
Thanks for all your help!
/DrZOO
|
|
|
|
|
you will have to write a comparison function that looks something like this:
bool date_sort(const SCHEDULEBLOCK &a, const SCHEDULEBLOCK &b)
{
return (a.ctDate < b.ctDate);
}
then you can sort it like this:
std::sort(vec.begin(), vec.end(), date_sort);
-c
Cheap oil. It's worth it!
|
|
|
|
|
It looks nice, but for some reason i get an error;
d:\Program Files\Microsoft Visual Studio .NET\Vc7\include\algorithm(1856):
error C2064: term does not evaluate to a function
which point to row 2 and 3 in the code below (from algorithm)
while (_First < _Pfirst
&& !_Pred(*(_Pfirst - 1), *_Pfirst)
&& !_Pred(*_Pfirst, *(_Pfirst - 1)))
--_Pfirst;
Can you please help me?
Should I pass some parameters to date_sort?
Thanks once again lifesaver
/DrZOO
|
|
|
|
|
it compiles fine for me.
#include "stdafx.h"
#include <vector>
#include <algorithm>
typedef struct tagSCHEDULEBLOCK
{ CTime ctDate;
CString csText;
}SCHEDULEBLOCK;
bool date_sort(const SCHEDULEBLOCK &a, const SCHEDULEBLOCK &b){ return (a.ctDate < b.ctDate);}
void Test()
{
std::vector<SCHEDULEBLOCK> vec;
std::sort(vec.begin(), vec.end(), date_sort);
}
-c
Cheap oil. It's worth it!
|
|
|
|
|
I think my problems are because my vector holds pointers (vector < SCHEDULEBLOCK* >).
I read Paul Wolfensberger's article "Using the std::sort() Method" before but I don't quite get it.
This code works...;
struct MySort
{
bool operator()(const SCHEDULEBLOCK* a, const SCHEDULEBLOCK* b)
{
return (a->ctBlockDate < b->ctBlockDate);
}
};
... but it doesn't look that nice.
/DrZOO
|
|
|
|
|
this defines the comparison operation as a function of the object. the way i showed defined the comparison as a global function. either way is fine.
DrZOO wrote:
it doesn't look that nice
it's STL - it shouldn't look nice!
-c
Cheap oil. It's worth it!
|
|
|
|
|
yup!
The earth is not dying. It is being killed.
|
|
|
|
|
Can anyone tell me, how can I implement Show desktop button without IShellDispatch4 object? Well I can get desktop window handle, I can go through list of child windows and minimize them, but not all of theese are aplicable.
Thank You
Jirka
|
|
|
|
|
I haven't tried this, but I've got the hunch it should work: in your windows directory there's a shortcut file named Show Desktop.sfc . If you invoke it programmatically with ShellExecute the desktop should be bringed to the foreground. This has two problems:- In non-English versions of Windows, this shortcut file has a different name.
- This file is not present in Windows 95 (I think)
To workaround these two issues, simply copy and paste the shortcut to your app directory, rename it to whatever you please and execute this instead.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
It is what I don't want. This script call IShellDispatch4 method. Problem is, that copy .scf file is not enough. You need IShelDispatch4 interface, that You don't find on W95 and also on WindowsNT.
Jirka
|
|
|
|
|
Hi,
I have a BHO which can open urls in the current instance of IE or a new instance of IE. However, if I open a url in a new instance and then close the new window, and then try to browse to any other url from the original BHO, nothing happens! Below is my code:
VARIANT vFlags = {0};
vFlags.vt = VT_I4;
vFlags.lVal = navOpenInNewWindow;
CComVariant vtEmpty;
if(bInNewWindow)
m_spBrowser->Navigate(_bstr_t(sUrl), &vFlags, &vtEmpty, &vtEmpty, &vtEmpty);
else
m_spBrowser->Navigate(_bstr_t(sUrl), &vtEmpty, &vtEmpty, &vtEmpty, &vtEmpty);
VariantClear(&vFlags);
Any ideas why this is happening, and a solution?
Thanks!
Chris
|
|
|
|
|
What is a BHO? I often open a new instance of the users default internet browser by using this..
ShellExecute(NULL, NULL, _T("url:http://www.yahoo.com"), NULL, _T("C:\\WINNT"),SW_SHOW);
I know its probably not the answer you were looking for but maybe it's another option.
Rob
|
|
|
|
|
Hi,
A BHO is a Browser Helper Object, like an Explorer Bar. I usually do the ShellExecute() also, but if I use that, it opens the url in the current instance of IE instead of in a new browser window.
I've also noticed that when opening links in email and such, sometimes a new browser window is opened for a link and other times, the last browser window opened is used... ???
Chris
|
|
|
|
|
Say you have a dialog with 2 member controls,
a listview and a listbox and both handles WM_LEFTBUTTONDOWN.
Then you think you could set up something like this
BEGIN_MSG_MAP(CMainDlg)
CHAIN_MSG_MAP_MEMBER(moList)
CHAIN_MSG_MAP_MEMBER(moListBox)
END_MSG_MAP()
but offcourse that will not work since moList will always get to handle
the message since it is first in the list.
The next thing you think of then is to check the HWND in each
off the classes WM_LBUTTONDOWN handlers and set bHandled to FALSE and
skip processing if it does not match.
(which is a soultion that is asking for problems when you start reusing the
classes since you will often forget to do that)
And that does not work either since the HWND is not passed on to the message
handler.
Is there some good standard soultion to this?
Or do i have to dig out the HWND some way?
Or (horrible tought) have to write a BEGIN_MSG_MAP macro that passes on the HWND?
/Magnus
|
|
|
|
|
I don't think that is doing what you expect.
Take a look at contained windows and the ALT message maps if you want to handle messages sent to the controls in your dialog's message map.
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
You dont have to say t dont do what i expect.
Anyway, what i am trying is to create some standard custom controls.
And then i would like to use them by subclassing the controls on the dialog.
So i want the controls to be what they are and not some CContainedWindow members.
Surely you must be able to do that someway or WTL looses *BIG* to MFC in that respect.
/Magnus
|
|
|
|
|
If you are trying to create standard custom controls then why are you trying to process the button down messages in dialog's main message map?
Either you use contained windows or you subclass CEdit for example and have the message map in the subclass.
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
I am processing the messages there because thats where they are sent.
I have subclassed the control and i have the messagemap in the subclass, but
WIN32 send messages to childwindows to the parent window.
So either i am missing a big part of the picture here or there is
not possible to create custom controls in WTL that can be reused easily.
/Magnus
|
|
|
|
|
????
You mentioned WM_LBUTTONDOWN which shouldn't be redirected to the parent. But if you are talking about notification message, then look at the reflect macros. This will allow you to reflect the messages back to the control.
MFC does handle this a bit better. But ATL/WTL gives the the macros to do the what you need to do.
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
Yes i got the messages mixed up with notifications there, but
in this case even the WM_LBUTTONUP is sent to the parent and not to my
subclassed window.
It's a static control, maybe they are a special?
I remember someting (but not what) about them being special if you use the default id for them. (which i dont do in this case)
/Magnus
|
|
|
|
|
Ok, then at this point you are getting into specifics I know nothing about.
So I can't honestly contribute.
But if you want me to, I can try to make up crap that sounds good.
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|