|
If I create a DEVNAMES structure:
1.) How do I get CPrintDialog to use my DEVNAMES structure?
2.) How do I set up DEVNAMES so that the printer I want will be the 'default' when the CPRintDialog pops up?
|
|
|
|
|
I think 1 and 2 are the same question, so:
CPrintDialog dlgPrint(FALSE);
dlgPrint.m_pd.hDevMode = hDevMode;
dlgPrint.m_pd.hDevNames = hDevNames;
dlgPrint.DoModal();
If you don't have a DEVMODE you want to use, set dlgPrint.m_pd.hDevMode to NULL , and the defaults will be used.
Sometimes i only remember, The days when i was young Nowadays no one remembers when they were young and stupid... ADEMA, The Way You Like It
|
|
|
|
|
I don't really understand the DEVNAMES structure. I'm guessing that the WORD variables are used as pointers to char arrays that hold the values. I tried the following, but it doesn't set the default printer.
WORD dp = *"\\\\MCL002NT\\CLIREQ";
DEVNAMES myDevNames;
myDevNames.wDriverOffset = dp;
/*
Restore the saved flags so we can pop the dialog with DoModal().
rgc
*/
dlg.m_pd.Flags = save_flags;//PD_RETURNDEFAULT = FALSE;
::GlobalUnlock(dlg.m_pd.hDevNames);
// - - - - - - - - - - - - -
dlg.m_pd.hDevNames = &myDevNames;
dlg.m_pd.hDevMode = NULL;
dlg.DoModal();
|
|
|
|
|
Almost. They are offsets from the beginning of the structure. This lets you copy the whole thing around without worry, but also makes it somewhat more difficult to initialize:
const char* szDriverName = "winspool";
const char* szPrinterName = "\\\\MCL002NT\\CLIREQ";
const char* szPortName = "PRI15:CLIREQ_P1";
int nDriverEnd = sizeof(DEVNAMES) + strlen(szDriverName)+1;
int nPrinterEnd = nDriverEnd + strlen(szPrinterName)+1;
int nPortEnd = nPrinterEnd + strlen(szPortName)+1;
HANDLE hDevNames = ::GlobalAlloc(GHND, nPortEnd);
DEVNAMES* pDevNames = (DEVNAMES*)::GlobalLock(hDevNames);
pDevNames->wDefault = 0;
pDevNames->wDriverOffset = sizeof(DEVNAMES);
pDevNames->wDeviceOffset = nDriverEnd;
pDevNames->wOutputOffset = nPrinterEnd;
strcpy((char*)(pDevNames)+sizeof(DEVNAMES), szDriverName);
strcpy((char*)(pDevNames)+nDriverEnd, szPrinterName);
strcpy((char*)(pDevNames)+nPrinterEnd, szPortName);
::GlobalUnlock(hDevNames);
Note: this is *not* Unicode aware; you'll need to double all the offsets and sizes (except the size of the DEVNAMES structure itself) if you're doing a Unicode build.
Also Note: the print dialog functions work with memory handles. It might be possible to substitute pointers, but i've never seen it done this way, and so i doubt it.
Good Luck!
Developers that like shiny objects also dig case mods and scratch-and-sniff stickers. Klaus Probst, The Lounge
|
|
|
|
|
Ok... that works. Thanks!
I'm still trying to understand it. I guess I've just never had to deal with 'memory handles' at this level before.
Where does the port name come from and does it matter what I use there?
const char* szPortName = "PRI15:CLIREQ_P1";
|
|
|
|
|
Rick Crone wrote:
Where does the port name come from and does it matter what I use there?
I've always used EnumPrinters() to obtain this information. The example i made up; looks almost authentic though . Yes, it probably does matter what you use!
Printing, IMHO, is one of the most poorly documented things in Win32, and that's saying a lot. I recently had to implement a clone of the standard print dialog so that i could use it on a property sheet (but it had to work on Win95, so i couldn't use the Win2k print property sheet ), and i'm still tearing my hair out over little things that don't work as expected. Later today i'll be heading over to B&N to look for a book on it; i've had it with MSDN.
Developers that like shiny objects also dig case mods and scratch-and-sniff stickers. Klaus Probst, The Lounge
|
|
|
|
|
Thanks so much for all your help.
In my current work I'm really just using CPrintDialog to get the printer name. I'm doing my own opening of the printer with some low level stuff. I was only concerned that CPrintDilaog might fill the port name for me and might overwrite memory if I had not allow enough space for the port name before the call.
Hum... this kind of takes me back to my origional problem... I was concerned that I might be overwriting memory that I don't own.
I hope this way is safer. Maybe I should look at EnumPrinters() to see if that could help make this a safe call.
Thanks again!
|
|
|
|
|
Hello All!
I'm having a little bit of trouble passing a function pointer. I have a nice class called C4DTPGraph, which has a member function DoMatching, declared as follows:
void C4DTPGraph::DoMatching( bool (*FoundMatch)( UINT *aVertices, UINT cVertices ) )
I have another class CTracker, which has a member variable C4DTPGraph *m_pCorrGraph. It also has a function called CheckMatch, declared as follows
bool CheckMatch( UINT *aVindices, UINT cVindices );
Here's the problem: when I try and call C4DTPGraph::DoMatching(), passing a pointer to CheckMatch(), VC++ gets upset, saying
error C2664: 'DoMatching' : cannot convert parameter 1 from 'bool (unsigned int *,unsigned int)' to 'bool (__cdecl *)(unsigned int *,unsigned int)'
here's the function call it doesn't like:
m_pCorrGraph->DoMatching( CheckMatch );
Now I can't see what's wrong with that, but then again, I've not got much experience passing function pointers as arguments.
Can anyone shed some light on what I'm doing wrong?
TIA,
Pete
|
|
|
|
|
Try this...
extern "C" bool CheckMatch( UINT *aVindices, UINT cVindices );
Make sure you do the same thing when CheckMatch is actually defined.
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?
|
|
|
|
|
Tried that, and got
error C2059: syntax error : 'string'
Thanks anyway!
|
|
|
|
|
Refer to Mike Dunn's C++ FAQ. There is a special declaration that you have to add for class member functions.
|
|
|
|
|
That'll do it!
Sorry to waste everyone's time with a question that was in the FAQ
|
|
|
|
|
I can't find Xor function in VC or C++,Can anybody help me about it to find such a thing?
Mazy
"The path you tread is narrow and the drop is shear and very high,
The ravens all are watching from a vantage point near by,
Apprehension creeping like a choo-train uo your spine,
Will the tightrope reach the end;will the final cuplet rhyme?"Cymbaline-Pink Floyd
|
|
|
|
|
^ operator does that.
Tomasz Sowinski -- http://www.shooltz.com
- It's for protection - Protection from what? Zee Germans?
|
|
|
|
|
Really?nice Anyway,thank you very much.
Mazy
"The path you tread is narrow and the drop is shear and very high,
The ravens all are watching from a vantage point near by,
Apprehension creeping like a choo-train uo your spine,
Will the tightrope reach the end;will the final cuplet rhyme?"Cymbaline-Pink Floyd
|
|
|
|
|
I am having a very frustrating problem, and i'm hoping someone might have some experience with CListCtrl.
Basicly I have a list, and when someone changes their selection i call a function which traces information about the item selected.. this is the code that vc++ .net generated for me, and the 'UpdateButtonStates()' is my function..
// this function is called whenever the user changes the selection on the listctrl
void CCompanyMaint::OnLvnItemchangedComplist(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<lpnmlistview>(pNMHDR);
UpdateButtonStates(); // change the availability of the buttons based on who is selected
*pResult = 0;
}
so, this calls my function:
void CCompanyMaint::UpdateButtonStates(void)
{
if (m_lstCompanies.GetSelectionMark() != -1)
{
CString strTemp;
int nPos = m_lstCompanies.GetSelectionMark();
int nVal = m_lstCompanies.GetItemData(m_lstCompanies.GetSelectionMark());
strTemp.Format("Position = %i, nVal = %i, name = %s\n", nPos, nVal, m_lstCompanies.GetItemText( m_lstCompanies.GetSelectionMark(), 0));
TRACE(strTemp);
}
}
the problem is that the data which it gets is always the previously selected item, not the currently selected item.. in other words if i choose item 5, then item 1, then it displays item 5's info, when i select a different item then it shows the data for item 1.. its lagged behind one move.. it always shows the data from the item that just got unselected, not the one im currently selecting.. ive tried moving the UpdateButtonStates() function in the OnLvnItemchangedComplist to above and below and in between the generated code.. but it doesn't matter.. any suggestions?
-dz
|
|
|
|
|
Try to use UpdateButtonStates()as a couple. It means your code is:
void CCompanyMaint::OnLvnItemchangedComplist(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR);
UpdateButtonStates(); // change the availability of the buttons based on who is selected
UpdateButtonStates();
*pResult = 0;
}
I met a problem like that when I want to update user's action on my combobox, and I tried the solution above.
Hung Son
A Vietnamese student
i-g.hypermart.net
dlhson2001@yahoo.com
|
|
|
|
|
nope, just gives the bad output 2 times instead of once.. thanks for the suggestion tho
-dz
|
|
|
|
|
is there any chance that my getselectionmark() command is happening before the item actually gets selected somehow? i mean i have buttons for editing and deleting an item, and they always select the correct item in the list to edit or delete.. its just the function thats actually gets called when they change their selection that doesn't work.. ??
-dz
|
|
|
|
|
I've often had problems with monitoring list control selection changes. As a workaround, I used a timer to monitor the current selection every 200mSec. If it changed, I posted a custom message to respond to the new selection. Yes, I know this is a hack but I didn't have much of a choice.
/ravi
"There is always one more bug..."
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
Unfortunately im not very versed in timers, or throwing messages.. i suppose i could use some sort of time are call call the function directly as well?
the whole purpose was to enable/disable buttons based on the choice from the list.. i guess i could just give an error if they try to use the buttons..
-dz
|
|
|
|
|
I need to create an edit box that is split in two and its size and shape can be resized by the user.
|
|
|
|
|
I think your request made editbox like a grid. So you can use grid instead of.
Hung Son
A Vietnamese student
i-g.hypermart.net
dlhson2001@yahoo.com
|
|
|
|
|
I got the problem, that the combobox can be edited by the user. but i just want him to choose from my values in the list.
the option of "pulldown listfield" isn't of. cause i have to tell the combobox which value it should have, everytime the dialog comes up.
knows somebody any solution?
thanks for help.
Tom
|
|
|
|
|
You need to set the combo style to DROPLIST. You can do that through the resource editor.
Michael
|
|
|
|