|
I just mixed up two different names for the class in the WNDCLASS style and CreateWindow.
Tim Smith found the error here: http://www.codeproject.com/script/comments/forums.asp?forumid=1647&select=147264#xx147264xx
Thanks anyway
modified 12-Sep-18 21:01pm.
|
|
|
|
|
I'm glad the mistery solved This bears a moral (IMHO): when you said the same code worked inside an EXE, you obviously used some other code that you deemed equivalent (otherwise the same problem persists). Many debugging efforts are lost due to this kind of assumptions.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
You need a DLLMain (entry point) function for the DLL. Here's an example pulled from MSDN...
BOOL WINAPI DllMain(
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpReserved )
{
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Take the instance param from that function and pass it to your CreateLogWindow() function. Use that instanace in the window's class. This is the done the same way you would use WinMain in an executable.
Also, don't forget to specify the entry point to the linker when compiling the DLL -- this has to be done.
Jeremy L. Falcon
"The One Who Said, 'The One Who Said...'"
<nobr>
Homepage : Feature Article : Sonork = 100.16311
|
|
|
|
|
Well, hInstance HAS the value of hinstDLL.
But what do you mean by
Jeremy Falcon wrote:
don't forget to specify the entry point to the linker when compiling the DLL
?
modified 12-Sep-18 21:01pm.
|
|
|
|
|
The entry point is the starting address of the DLL -- the first of your code that's called. You need to let the linker know about it.
You need a user-defined entry point for the DLL. I believe it defaults to DLLMain, but if your DLL doesn't use that naming you must specify it somehow. I chose using the linker and specify it anyway regardless. I'm crazy like that.
I'm assuming you're using VC6...
Goto project settings.
Link Tab
Category: Output
You'll see an edit box for the Entry-point symbol. Put the name of your entry function in there.
Jeremy L. Falcon
"The One Who Said, 'The One Who Said...'"
<nobr>
Homepage : Feature Article : Sonork = 100.16311
|
|
|
|
|
Ummm...
The class name in WndClass is "Testprogramm" and in CreateWindow it is "LogWindow".
Hopefully that is it.
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?
|
|
|
|
|
Ummm how stupid
I just corrected it and suddenly it works
Thanks a lot!
modified 12-Sep-18 21:01pm.
|
|
|
|
|
So how did you manage to run this code from .exe?
Tomasz Sowinski -- http://www.shooltz.com
- It's for protection - Protection from what? Zee Germans?
|
|
|
|
|
It think I copy&pasted the code and later changed some strings, but unfortunately not all
really stupid
modified 12-Sep-18 21:01pm.
|
|
|
|
|
Hi Tim! You must be in a fresher mental state than I am, how simple yet elusive. The duck's for you
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
It's amazing how really looking at the code helps. That deserves a doh for me too!
Jeremy L. Falcon
"The One Who Said, 'The One Who Said...'"
<nobr>
Homepage : Feature Article : Sonork = 100.16311
|
|
|
|
|
Hehehe, when I saw what the problem was, I knew everyone was going to kick themselves for not seeing it.
We have all looked at code for 30 hours on end just to have some jackass spend 5 minutes looking over our shoulder and see the problem.
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 have a CListCtrl that I would like to put images onto. I create a bitmap and bitblt an image into it, this works fine as I have tested that the image in the bitmap is valid by printing it to the screen. When I add this bitmap to the CImageList then accociate it with the CListCtrl a black box appears next to the column instead of my image! Here is the code I am using (I have tried many different values but I think it has something to do with the bitmap not being compatible or something)
CDC dc, *pDC = GetDC();
CBitmap cBmp;
m_ChatNicksImages.Create(16, 16, ILC_COLORDDB | ILC_MASK, 8, 1);
dc.CreateCompatibleDC(pDC);
cBmp.CreateCompatibleBitmap(pDC, 16*8, 16);
dc.SelectObject(cBmp);
m_Skin.BitBlt(&dc, 0, 0, 16*8, 16, 195, 250);
m_ChatNicksImages.Add(&cBmp, RGB(0, 255, 0));
m_ChatNicksCtrl.SetImageList(&m_ChatNicksImages, LVSIL_SMALL);
cBmp.DeleteObject();
ReleaseDC(pDC);
These are members of my dialog:
CImageList m_ChatNicksImages;
CListCtrl m_ChatNicksCtrl;
Any help is appreciated, Thanks.
|
|
|
|
|
At the time you are trying to add the bitmap to the image list, it is still selected into your memory device context. You should restore the previous bitmap before continuing:
dc.CreateCompatibleDC(pDC);
cBmp.CreateCompatibleBitmap(pDC, 16*8, 16);
CBitmap* pBmpOld = dc.SelectObject(&cBmp);
m_Skin.BitBlt(&dc, 0, 0, 16*8, 16, 195, 250);
dc.SelectObject(pBmpOld);
Note also that you want to pass a pointer to the bitmap into dc.SelectObject() (as i've shown).
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
|
|
|
|
|
Thank you this worked perfectly!
|
|
|
|
|
I want to specify a ‘default’ printer that may not be the Windows users default printer when the print dialog executes.
This code works, but I am concerned about a few of areas.
1.) See where I’m using the cp variable to update the printer name? Could this code overwrite memory beyond the area allocated for the printer name?
2.) Notes from the HELP file indicate I should free the DC. Do I need to do that? How would I do it?
3.) I’m saving and restoring flags to get the print dialog to display. I bet there is a better solution to that problem, what is it?
CPrintDialog dlg(FALSE,
PD_ALLPAGES |
PD_HIDEPRINTTOFILE |
PD_NOPAGENUMS |
PD_RETURNDC |
PD_USEDEVMODECOPIES);
/*
We are saving the current Flags here so we can put them back after the call
to GetDefaults()... calls to DoModal() will not pop the dialog unlesss we
do this.
rgc
*/
DWORD save_flags = dlg.m_pd.Flags;
dlg.GetDefaults();
/* **** from the HELP files ****
Note that when you call the constructor with bPrintSetupOnly set to FALSE,
the PD_RETURNDC flag is automatically used. After calling DoModal,
GetDefaults, or GetPrinterDC, a printer DC will be returned in m_pd.hDC.
This DC must be freed by the caller of CPrintDialog.
*/
LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(dlg.m_pd.hDevNames);
// next line is test code to get the current printer
//LPCTSTR lpszDevice = (LPCTSTR)lpDev + lpDev->wDeviceOffset;
char *cp = (char *)lpDev + lpDev->wDeviceOffset;
CString def_prn = "\\\\MCL002NT\\CLIREQ";
strcpy(cp,def_prn);
// next line is test code to check to see that the printer has changed
//lpszDevice = (LPCTSTR)lpDev + lpDev->wDeviceOffset;
/*
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.DoModal()
// - - - - - - - - - - - - -
Rick Crone
|
|
|
|
|
- Potentially. The
DEVNAMES structure is pretty simple; creating a new one (or better yet, enumerating installed printers & just selecting the one you want) isn't hard; i'd avoid what you're doing now. DeleteDC() - Hmm, you could just use a separate
CPrintDialog ... nothing wrong with saving and restoring flags that i know of though, unless it bugs your sense of style.
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
|
|
|
|
|
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
|
|
|
|
|