|
Actually the problem was reading in the strings with the GetProfileString() call I had:
theApp.GetProfileString("CheckPrinter", "DeviceName", csDeviceName);
which should have been:
csDeviceName=theApp.GetProfileString("CheckPrinter", "DeviceName", "");
so that was an easy fix.
Now the function is working fine, except when the program is closed. After I reopen the program I get an unhandled exception in COMDLG32.DLL (0xC0000005) Access Violation after the dlg.DoModal() call. When debugging the exception comes after executing: m_pd.hwndOwner = PreModal(); . Here is the code from the MFC file DLGPRNT.CPP:
<br />
int CPrintDialog::DoModal()<br />
{<br />
ASSERT_VALID(this);<br />
ASSERT(m_pd.Flags & PD_ENABLEPRINTHOOK);<br />
ASSERT(m_pd.Flags & PD_ENABLESETUPHOOK);<br />
ASSERT(m_pd.lpfnPrintHook != NULL);
ASSERT(m_pd.lpfnSetupHook != NULL);
<br />
m_pd.hwndOwner = PreModal();<br />
int nResult = ::PrintDlg(&m_pd);<br />
PostModal();<br />
return nResult ? nResult : IDCANCEL;<br />
}
I did check the dmDriverExtra member and it was saved correctly.
I also tried using the SelectPrinter function by just replacing:
dlg.m_pd.hDevMode = hDEVMODE;<br />
dlg.m_pd.hDevNames = hDEVNAMES;
with:
theApp.SelectPrinter(hDEVNAMES, hDEVMODE, FALSE);
while it didn't throw an error, it didn't populate the CPrintDialog with the correct printer/values. This application has a MDI, and what I am doing is an attempt to setup a different printer for checks, cash receipts, and reports with out user interaction (once they have been setup of course).
Thanks again,
Chad
|
|
|
|
|
OK so the problem was saving the dmDriverExtra param, which contains the number of bytes of private driver-data that follow the structure. So adding dm->dmDriverExtra=0; before saving the DEVMODE structure fixed it. Here is the completed function, included for completeness:
<br />
BOOL CMainFrame::SetupPrinter(CString csPrinter, CPrintDialog* pDlg)<br />
{<br />
DEVMODE *hDevMode=NULL;<br />
UINT nl;<br />
CString csDeviceName, csPortName, csDriverName;<br />
theApp.GetProfileBinary(csPrinter, "DevMode", (LPBYTE*)&hDevMode, &nl);<br />
csDeviceName=theApp.GetProfileString(csPrinter, "DeviceName", "");<br />
csPortName=theApp.GetProfileString(csPrinter, "PortName", "");<br />
csDriverName=theApp.GetProfileString(csPrinter, "DriverName", "");<br />
<br />
BOOL bLoadedDialog=TRUE;<br />
if(pDlg==NULL)<br />
{<br />
pDlg=new CPrintDialog(TRUE);<br />
bLoadedDialog=FALSE;<br />
}<br />
<br />
LPDEVMODE pDM;<br />
HGLOBAL hDEVNAMES;<br />
HGLOBAL hDEVMODE;<br />
BOOL bLoadedData=FALSE;<br />
BOOL bCancel=FALSE;<br />
<br />
if(!csDeviceName.IsEmpty()||!csPortName.IsEmpty()||!csDriverName.IsEmpty()||hDevMode!=NULL)<br />
{<br />
bLoadedData=TRUE;<br />
<br />
pDM = hDevMode;<br />
int size = sizeof(DEVMODE);<br />
hDEVMODE = GlobalAlloc(GHND, size);<br />
void *pV = GlobalLock(hDEVMODE);<br />
memcpy(pV, pDM, size);<br />
GlobalUnlock(pV);<br />
delete pDM;<br />
pDM = NULL;<br />
<br />
size = sizeof(DEVNAMES);<br />
size += (csDeviceName.GetLength() + 1) * sizeof(TCHAR);<br />
size += (csPortName.GetLength() + 1) * sizeof(TCHAR);<br />
size += (csDriverName.GetLength() + 1) * sizeof(TCHAR);<br />
<br />
hDEVNAMES = GlobalAlloc(GHND, size);<br />
LPDEVNAMES pDN = (LPDEVNAMES)GlobalLock(hDEVNAMES);<br />
pDN->wDefault = 0;<br />
pDN->wDriverOffset = sizeof(DEVNAMES);<br />
pDN->wDeviceOffset = (WORD)(pDN->wDriverOffset + csDriverName.GetLength() + 1);<br />
pDN->wOutputOffset = (WORD)(pDN->wDeviceOffset + csDeviceName.GetLength() + 1);<br />
_tcsncpy((TCHAR *)((int)pDN + pDN->wDriverOffset), csDriverName, csDriverName.GetLength());<br />
_tcsncpy((TCHAR *)((int)pDN + pDN->wDeviceOffset), csDeviceName, csDeviceName.GetLength());<br />
_tcsncpy((TCHAR *)((int)pDN + pDN->wOutputOffset), csPortName, csPortName.GetLength());<br />
GlobalUnlock(pDN);<br />
<br />
pDlg->m_pd.hDevMode = hDEVMODE;<br />
pDlg->m_pd.hDevNames = hDEVNAMES;<br />
}<br />
<br />
if(pDlg->DoModal()==IDOK)<br />
{<br />
DEVMODE *dm=pDlg->GetDevMode();<br />
dm->dmDriverExtra=0;
theApp.WriteProfileBinary(csPrinter, "DevMode", (LPBYTE)dm, sizeof(DEVMODE));<br />
theApp.WriteProfileString(csPrinter, "DeviceName", (LPCTSTR) pDlg->GetDeviceName());<br />
theApp.WriteProfileString(csPrinter, "PortName", (LPCTSTR) pDlg->GetPortName());<br />
theApp.WriteProfileString(csPrinter, "DriverName", (LPCTSTR) pDlg->GetDriverName());<br />
<br />
if(bLoadedData)<br />
GlobalUnlock(pDM);<br />
}<br />
else<br />
{<br />
bCancel=TRUE;<br />
if(bLoadedData)<br />
GlobalFree(hDEVMODE);<br />
}<br />
<br />
if(bLoadedData)<br />
GlobalFree(hDEVNAMES);<br />
<br />
if(!bLoadedDialog)<br />
delete pDlg;<br />
<br />
if(bCancel)<br />
return FALSE;<br />
else<br />
return TRUE;<br />
}<br />
|
|
|
|
|
Ok so now it's time to figure out how to use the data that I saved...
In the view's OnPreparePrinting() function how can I override the function so that it won't display the CPrintDialog unless the paramaters that I saved previously are missing? The problem is the CPrintInfo's m_pPD->m_pd.hDC var can't be NULL after the function is called.
Secondly to switch between printers can I just have a call like:
pDC->CreateDC(m_csCashDriverName, m_csCashDeviceName, m_csCashPortName, m_hCashDevMode);
in the OnDraw() function of my view class when I want to send the output to a different printer?
Thanks, Chad
|
|
|
|
|
In OnPreparePrinting, do not call DoPreparePrinting if you do not want the print dialog.
Read MSDN[^] to get a complete over view of printing in MFC.
This page is linked from the page I gave you earlier, be sure to read the entire section on printing, follow the links given.
Maybe also read the printing articles here on CP[^].
Just a suggestion, but sometimes the MFC framework does not fit the model you want to use, so rather than fight MFC, it may be better to roll your own printing model that better fits what you are trying to do.
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" mYkel - 21 Jun '04
Within you lies the power for good - Use it! Honoured as one of The Most Helpful Members of 2004
|
|
|
|
|
Quick question: How do I find out what Version #, Service Pack(s), and other versioning info for my Visual Studio 6.0?
When I click Help --> About Visual C++, I don't get anything useful.
Thanks.
Johnny
|
|
|
|
|
MS info about service packs is dreadful. Do you have VB installed? If so, it tells you on its splash screen which SP it has. In which case the chances are that VC++ will be at the same level.
However, a few years ago I remember there being a web page somewhere which listed various DLLs and their versions against the SP versions.
Kevin
|
|
|
|
|
Thanks. I looked in a few places (Add/Remove Programs, through Visual InterDev 6.0) nothing very useful. InterDev reported (SP5), but I didn't think I was that current so it makes me suspicious of this number tied into Visual Studio (VC++ 6.0).
Anyways, if I need to get current (establish a baseline for me and my fellow developers), I can get the latest Service Pack http://msdn.microsoft.com/vstudio/downloads/updates/sp/vs6/sp5/faq.aspx[^]
as it sez that SPs are cumulative and that the latest encompasses the fixes from the previous SPs.
Thanks!
Johnny
|
|
|
|
|
Well, I guess if all the constituent apps. were installed at the same time then V InterDev being at SP5 probably means they all are. However, if any indvidual apps. were reinstalled then you'd have to reapply the SP. BTW, are you aware that the latest SP is SP6? It was released about a year ago.
Kevin
|
|
|
|
|
See here:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\6.0\ServicePacks
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
|
|
|
|
|
Hi everyone!
I'm trying to develop an application that uses a control just like the one used on Windows XP to test the hardware of microphone. Looks like a progressBar, that every time that you speaks on the microphone, it goes up and down showing something like the frequence of the wave.
Does anybody knows how can I implement this kind of control?
thanks,
cheers!
|
|
|
|
|
|
That's it!
thanks Ravi!
cheers!
|
|
|
|
|
Who can teach me how to show different view in the CSplitterWnd ?
I want to show different view in the second pane if I click the button in the
first pane.
|
|
|
|
|
There are several examples available here at CP and on the Web. Here's what I've implemented.
I have a CSplitterWndEx object that belongs to the frame class. In the left pane's handler (where the different view type is selected) I get a pointer to the frame's CSplitterWndEx object, and then call that object's ReplaceView() method. The ReplaceView() method looks like:
if ((GetPane(nRow, nCol)->IsKindOf(pViewClass)) == TRUE)
return;
CListView pActiveView = (CListView *) GetParentFrame()->GetActiveView();
if (NULL == pActiveView || GetPane(nRow, nCol) == pActiveView)
bSetActive = TRUE;
CDocument *pDoc = ((CListView *) GetPane(nRow, nCol))->GetDocument();
pDoc->m_bAutoDelete = FALSE;
((CListView *) GetPane(nRow, nCol))->DestroyWindow();
pDoc->m_bAutoDelete = TRUE;
CCreateContext context;
context.m_pNewViewClass = pViewClass;
context.m_pCurrentDoc = pDoc;
context.m_pNewDocTemplate = NULL;
context.m_pLastView = NULL;
context.m_pCurrentFrame = NULL;
CreateView(nRow, nCol, pViewClass, size, &context);
pNewView = (CListView *) GetPane(nRow, nCol);
if (TRUE == bSetActive)
GetParentFrame()->SetActiveView(pNewView);
RecalcLayout();
pDoc->UpdateAllViews(NULL); I would call this method with something like:
pMainFrame->GetSplitterWnd()->ReplaceView(0, 1, RUNTIME_CLASS(CMeetView), CSize(0, 0));
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
|
|
|
|
|
HI ,
I hav to mak a project on packet capturing. I recently discovered a library called WinPCap. This works efficiently for networks. But i cannot include the library and work with it. It doesnot except the commands used in WinPCap. Anyone who hav used it in his software will be of great help to me. Guide me how to use WinPCap in my project with VC++ MFC.
THANK YOU
I require ur help
|
|
|
|
|
why dont u use windows raw sockets for packet capturing.
Tutorial Here
|
|
|
|
|
do u know the differences between command.com and cmd.exe?
i guess they do exactly same things.
thx
includeh10
|
|
|
|
|
command.com is used for backward compatibility with 16-bit and Windows 9x applications. cmd.exe is not available on either.
One obvious difference is how each handles the space character. For example, the command md this folder has spaces would fail with command.com but would work with cmd.exe, although four folders would get created. To remedy this, the folder name must be surrounded by quotation marks (md "this folder has spaces").
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
|
|
|
|
|
1. DavidCrow wrote:
cmd.exe is not available on either
what does it mean? please explain.
2. is "MS-DOS prompt" command.com or cmd.exe or else?
3. do all windows OS from win95 to NT, XP etc contain both of them?
i know almost NULL about DOS, currently I have to use it.
includeh10
|
|
|
|
|
includeh10 wrote:
what does it mean? please explain.
It means that cmd.exe is not part of MS-DOS or Windows 9x.
includeh10 wrote:
2. is "MS-DOS prompt" command.com or cmd.exe or else?
Based on my earlier reply, it's obvious that MS-DOS uses command.com.
includeh10 wrote:
3. do all windows OS from win95 to NT, XP etc contain both of them?
No. cmd.exe is not part of Windows 9x.
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
|
|
|
|
|
command.com is a 16-bit DOS-compatible application, although with a few extensions that allow it to launch 32-bit applications. It runs in the Virtual 8086/NT Virtual DOS Machine environment. It only supports the DOS-compatible built-in command options. Compared to cmd.exe , the input is distinctly unresponsive on modern processors (at least on P4 family).
cmd.exe is a 32-bit Windows Console subsystem application. It supports numerous command extensions over the DOS-compatible built-in options (for details, see help ). It supports filename and directory completion (not enabled by default on Windows 2000, but is on XP - press Tab to complete the current entry). It natively supports command history, a feature requiring the use of the doskey utility for command.com .
64-bit Windows does not support DOS applications, including command.com . This is due to a lack of processor support. Many traditional DOS extensions such as more.com are in fact full 32-bit Windows Console subsystem binaries on Windows XP, despite the COM extension. If you use more from command.com , Windows loads a copy of cmd.exe as an intermediary.
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
Hi,
I am looking for a report generation solution for a desktop engineering application. For now, this will be a hobby project so I am looking for a library (or a suite of libraries) that are free or LGPL or cheap (ei less than $500 in total). Note I excluded GPL, because this is also a technology search for a commercial application. For my hobby project I want a multi platform solution (*nix, Windows and Mac?), but for the commercial application Windows support is enough. If the solution is using a commercial library it must be royalty free.
. This report will be a multi page report, containing tables(lots of them), figures (most probably png outputs from a(n) OpenGL/DirectX/GDI frame), formulas and of course normal text.
. There should be a previewer that I can embed into my application.
. It should support printing directly.
. Editing is perhaps the most ambiguous part. Editing will be quite limited. I do not want the user to edit the values in the tables, but add additional text. It would be great if this could be done in the preview mode, ie sizing a table in order to add a note next to it, or add a sentence to an existing paragraph.
. Most of the time, the report generated will be stand alone, meaning that the user will print it directly within the application. But it is also possible that this report will be a part of a bigger report that most probably will be prepared in MS Office and/or OpenOffice so I should also be able to export to some format that these applications can import without losing too much information along the way (formulas will be tricky). Of course this conflicts with the limited editing requirement, but you can not have it all (or can I?)
My solutions:
1. Use (la)Tex. I am familiar with (la)Tex. So I can generate the report in tex and convert to some format (ie pdf, rtf or whatever) and display/print it. For the PDF part I can embed Acrobat Reader in to my application, although I do not know how to do this in Linux but, I can just look at the source code of an application which does it. Or I can use GhostScript, although their web site requires you to email them for detailed information on commercial usage, I can do that if I find this more usable than embedding Acrobat Reader.
2. Use rtf. Although I am familiar with rtf format, I am not really sure about table and/or formula support in rtf.
3. Use pdf. I am not really familiar with pdf, but there are libraries around that will generate pdfs for you with a nice C/C++ interface. The downside is I have to implement all page layout algorithms myself including formulas, tables etc.
4. Embed MS Word into my application. I know how to do this, but I do not know how much control will I have in terms of generating a complete report with formulas and tables (definitely I will have much more control then Acrobat Reader). I am hoping the same thing can be done with OpenOffice too, at least for other platforms that I want to support. I do not like this solution very much, since you require the user to buy quite expensive product (for MS Word), and/or download a big installation for a relatively small (ie less than 5MB) application. Note, (la)Tex may also suffer from the same problem, depending on which extensions I end up using.
5. And finally as always, implement something from scratch.
Although I will prefer C/C++, I am open to suggestions to libraries that are written in other languages.
Thank you in advance...
Orhun Birsoy
|
|
|
|
|
i want that when the aplication star one of the 5 radio buttons is set active as default, because in my program all radio buttons are set as inactive you have to set it qhen you star the program.
|
|
|
|
|
The easiest and most reliable way is to create a CButton member variable for each. Then in the dialog's OnInitDialog() method, call the SetCheck(BST_CHECKED) method of the button you want checked.
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
|
|
|
|
|
It doesnt work
error C2065: 'SetCheck' : undeclared identifier
|
|
|
|
|