|
Have you stepped through the IsDerivedFrom() function?
How are you calling the CSingleDocTemplate c'tor?
You may be right I may be crazy -- Billy Joel --
Within you lies the power for good, use it!!!
|
|
|
|
|
It's a nothing-fancy MFC SDI app. The only thing I changed in the CDocTemplate was the view class.
What's really stupid is I've done this before, and I can't think of anything I'm forgetting.
The trace through IsDerivedFrom doesn't make any sense. It's comparing pointers to objects instead of doing something like checking the results of a dynamic_cast to the desired base class. Here's that function - the bold parts are the lines executed:
BOOL CRuntimeClass::IsDerivedFrom(const CRuntimeClass* pBaseClass) const
{
ENSURE(this != NULL);
ASSERT(AfxIsValidAddress(this, sizeof(CRuntimeClass), FALSE));
ENSURE(pBaseClass != NULL);
ASSERT(AfxIsValidAddress(pBaseClass, sizeof(CRuntimeClass), FALSE));
const CRuntimeClass* pClassThis = this;
#ifdef _AFXDLL
for ( ; ; )
#else
while (pClassThis != NULL)
#endif
{
if (pClassThis == pBaseClass)
return TRUE;
#ifdef _AFXDLL
if (pClassThis->m_pfnGetBaseClass == NULL)
break;
pClassThis = (*pClassThis->m_pfnGetBaseClass)();
#else
pClassThis = pClassThis->m_pBaseClass;
#endif
}
return FALSE;
}
If checks the following classes:
CTestGridView3
CView <------------ !!!!!
CCmdTarget
CObject
NULL
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
In the DLL, I had to set the "Characterset" property (under Configuration Properties/General) to "Not Set". Then everything works. :/
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
Yeah, I tried it and noticed that I get the same error if the DLL and main app are built with different settings. I guess that means you can not mix MBCS and DBCS.
You may be right I may be crazy -- Billy Joel --
Within you lies the power for good, use it!!!
|
|
|
|
|
I'm guessing that "not set" means that the build falls back to the default of SBCS, which should not be used anymore.
|
|
|
|
|
The app is set to MBCS. If I set the DLL to "not set" or "MBCS", it works. If I set the DLL to Unicode, it doesn't work.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
Hello,
I have some questions about using global (system wide) hooks in Win32. I've got a simple app loading my simple DLL which sets up a WH_MOUSE hook:
m_hhook=SetWindowsHookEx(WH_MOUSE,MouseProc,m_hmod,0); (inside DLL)
My MouseProc is: (also inside DLL)
HOOKTEST2DLL_API LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
MOUSEHOOKSTRUCT *mhs=(MOUSEHOOKSTRUCT *)lParam;
if(nCode < 0) // do not process the message
return CallNextHookEx(m_hhook, nCode, wParam, lParam);
else
{
if((nCode==HC_ACTION) && (wParam==WM_LBUTTONDBLCLK))
{
PostThreadMessage(m_appthreadid,WM_APP+1,0,0);
m_mouseproc_counter++;
}
return CallNextHookEx(m_hhook, nCode, wParam, lParam);
}
}
I have also some variables in shared section of DLL which are initialised using:
HOOKTEST2DLL_API void fnInit()
{
m_hwnd_app=NULL; //main application window HWND
m_hhook=NULL; //WH_MOUSE hook handle
m_hwnd_desktop=::GetDesktopWindow(); //desktop window handle
m_mouseproc_counter=0; //mouse-dblclicks counter
m_appthreadid=NULL; //main application's thread ID
m_hmod=GetModuleHandle("HookTest2DLL.dll"); //DLL module handle
}
My questions are:
1) Why PostMessage(m_hwnd_app,WM_APP+1,0,0) doesn't work? Variable m_hwnd_app is set up after DLL is loaded and points to the main window of my simple MFC app. PostThreadMessage(m_appthreadid,WM_APP+1,0,0) works fine.
2) When I detect a doubleclick on desktop screen, in my MOUSEHOOKSTRUCT structure hwnd is set to 0x10094 (::GetDesktopWindow() returns 0x10014) but even when I double-click on any desktop icon (ie My Computer) I'm getting this event. Is it possible to filter out those events connected with double-clicking on desktop icons??
3) What is the best way of communicating between DLL and host application in case, when DLL could be injected into other threads/processes? Can I use variables in shared data section of my DLL or only PostThreadMessage() should be used?
Thank for any help
Pat.
|
|
|
|
|
To my question 2)
Using Spy++ I have figured out, that capturing additional message LVM_HITTEST could solve my problem. When double-clicking on desktop, Windows generates LVM_HITTEST message with nIndex set to icon which we are clicking on, or -1 when we click on desktop. Messages come in this order (in case of doubleclick)
1.LVM_HITTEST (first click)
2.LVM_HITTEST (second click)
3.WM_LBUTTONDBLCLK
...so it's safe to cache last LVM_HITTEST message and when WM_LBUTTONDBLCLK happen, just check nIndex of last cached message, if it's -1 we have a double-click on desktop.
Any faster/simpler solution?? (it would be nice if I could detect it based on only one message)
Another question is how to capture LVM_HITTEST message? Another system-wide hook?:/
Thanks for any help
Pat.
|
|
|
|
|
Finally I've found a way to filter-out all icons connected WM_LMOUSEDBLCLK messages. My MouseProc() now looks like this:
HOOKTEST2DLL_API LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
MOUSEHOOKSTRUCT *mhs=(MOUSEHOOKSTRUCT *)lParam;
LVHITTESTINFO pinfo;
if(nCode < 0) // do not process the message
{
return CallNextHookEx(m_hhook, nCode, wParam, lParam);
}
else
{
if((nCode==HC_ACTION) && (wParam==WM_LBUTTONDBLCLK))
{
if(mhs->hwnd==m_hwnd_desktop) //==0x10094
{
pinfo.pt=mhs->pt;
if(SendMessage(m_hwnd_desktop,LVM_HITTEST,0,(LPARAM)&pinfo)==-1)
{
PostThreadMessage(m_appthreadid,WM_APP+1,mhs->pt.x,mhs->pt.y);
m_mouseproc_counter++;
}
}
}
return CallNextHookEx(m_hhook, nCode, wParam, lParam);
}
}
It seems to be fine, I'm getting WM_APP+1 messages only when I double-click on desktop window and not on any desktop icon
Well, this leads me to another question:
4) How to find in a system-friendly and Windows compatible way this 'magic' window handle 0x00010094? Using Spy++ I could find out the class name and window name. My current code looks like this:
HWND h1=::FindWindowEx(NULL,NULL,"Progman","Program Manager");
HWND h2=::FindWindowEx(h1,NULL,"SHELLDLL_DefView",NULL);
m_hwnd_desktop=::FindWindowEx(h2,NULL,"SysListView32",NULL);
...and it's working fine, but that's strange that a single line:
m_hwnd_desktop=::FindWindowEx(NULL,NULL,"SysListView32","ListView");
...does NOT work (returns NULL). Is this method 'safe and compatible'?
Pat.
|
|
|
|
|
PatrykDabrowski wrote: PostThreadMessage(m_appthreadid,WM_APP+1,0,0);
instead of using the WM_APP+1, use RegisterWindowMessage to create a unique message.
nave
|
|
|
|
|
Hi All,
I am studying multithreading with Visual Studio 2005.
I have an error with one sample from "Multithreading Applications in Win32 - Jim Beveridge & Robert"
1>.\SearchFile.cpp(44) : error C2664: '_beginthreadex' : cannot convert parameter 3 from 'DWORD (__stdcall *)(void *)' to 'unsigned int (__stdcall *)(void *)'
/*
SerarhFil.cpp
*/
#include <windows.h>
#include <process.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include "MtVerify.h"
DWORD WINAPI SearchProc(void *arg);
#define MAX_THREADS 3
HANDLE hThreadLimitSemaphore;
char szSearchFor[1024];
int main(int argc, char *argv[])
{
WIN32_FIND_DATA* lpFindData;
HANDLE hFindFile;
HANDLE hThread;
DWORD dummy;
int i;
if(argc != 2)
{
printf("Usage: %s <search-string>\n", argv[0]);
return EXIT_FAILURE;
}
strcpy(szSearchFor, argv[1]);
lpFindData = (WIN32_FIND_DATA*) calloc(1, sizeof(WIN32_FIND_DATA));
MTVERFY(hThreadLimitSemaphore = CreateSemaphore(NULL, MAX_THREADS, MAX_THREADS, NULL));
hFindFile = FindFirstFile("*.c", lpFindData);
if(hFindFile == INVALID_HANDLE_VALUE);
return EXIT_FAILURE;
do{
WaitForSingleObject(hThreadLimitSemaphore, INFINITE);
//HERE
MTVERFY(hThread = (HANDLE) _beginthreadex(NULL, 0, SearchProc, lpFindData, 0, &dummy));
MTVERFY(CloseHandle(hThread));
lpFindData =(WIN32_FIND_DATA*)calloc(1, sizeof(WIN32_FIND_DATA));
}while(FindNextFile(hFindFile, lpFindData));
FindClose(hFindFile);
for(i=0; i<max_threads;i++)
waitforsingleobject(hthreadlimitsemaphore,="" infinite);
="" mtverfy(closehandle(hthreadlimitsemaphore));
="" return="" exit_success;
}
dword="" _stdcall="" searchproc(void="" *arg)
{
="" win32_find_data="" *lpfinddata="(WIN32_FIND_DATA*)arg;
" char="" buff[1024];
="" file*="" ptrfile;
="" ptrfile="fopen(lpFindData-">cFileName, "r");
if(!ptrFile)
return EXIT_FAILURE;
while(fgets(buff, sizeof(buff), ptrFile))
{
if(strstr(buff,szSearchFor))
printf("%s: %s", lpFindData->cFileName, buff);
}
fclose(ptrFile);
free(lpFindData);
MTVERFY(ReleaseSemaphore(hThreadLimitSemaphore, 1, NULL));
}
Yonggoo
|
|
|
|
|
Yonggoo wrote: 1>.\SearchFile.cpp(44) : error C2664: '_beginthreadex' : cannot convert parameter 3 from 'DWORD (__stdcall *)(void *)' to 'unsigned int (__stdcall *)(void *)'
Yonggoo wrote: MTVERFY(hThread = (HANDLE) _beginthreadex(NULL, 0, SearchProc, lpFindData, 0, &dummy));
Yonggoo wrote: DWORD _stdcall SearchProc(void *arg)
_beginthreadex requires the thread proc that it calls to return an unsigned int . You are passing it a function that returns a DWORD . There is no built in conversion from a DWORD to an unsigned int . Change the return type of the SearchProc to an unsigned int .
You may be right I may be crazy -- Billy Joel --
Within you lies the power for good, use it!!!
|
|
|
|
|
Greetings,
I have a custom class I'm building in an MDI application. How do I use a resource ID (i.e. IDB_CAR1) in my class? I called a method using that resource ID, but my application can't find it even though it is a resource. Is there an "#include" I'm missing somewhere for my custom class? What's really strange, is that when I hover the mouse over the offending variable, it gives me a tooltip stating "define IDB_CAR1 130" so it knows what it is, but when I try to compile it, it tells me that it is an unknown identifier.
Any help would be greatly appreciated.
Thanks,
BP
-- modified at 13:57 Sunday 7th January, 2007
|
|
|
|
|
Did you #include "resource.h" in your cpp file?
You may be right I may be crazy -- Billy Joel --
Within you lies the power for good, use it!!!
|
|
|
|
|
PJ Arends - you are the man!!!!
Thanks,
BP
|
|
|
|
|
Hi guys
I want to hook the CreateFile function that programs call and record all the file names that an app opens and after call the real CreateFile
pls any help here would be apreciated becose Im in the dark with hooking function othere dll's
|
|
|
|
|
|
How to check the sign bit in 8 bit integer.? is this MSB? thanks.
|
|
|
|
|
ikbahrian wrote: How to check the sign bit in 8 bit integer.? is this MSB?
Yes.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Just use a check like this:
if (var<0)
If the variable in of an unsigned type add a cast to the signed version. For example, assume var is an unsigned int :
if (static_cast<int>(var)<0)
Steve
|
|
|
|
|
Hi all, i am a beginer in the area and i did a small program and i get Link errors, can you tell me what is the problem:
file.h
#include <iostream.h>
class CustBase
{
char * custName;
public:
CustBase(){custName=NULL;}
void Print();
};
file.cpp
#include "CustBase.h"
void CustBase::Print()
{
if(this->custName != NULL)
cout<<this->custName<
|
|
|
|
|
ytubis wrote: Main.obj : error LNK2005: "public: void __thiscall CustBase::Print(void)" (?Print@CustBase@@QAEXXZ) already defined in CustBase.obj
The message above comes because in the code below
ytubis wrote: Main
#include "CustBase.cpp"
void main()
{
CustBase a;
a.Print();
}
you have to include the header file (CustBase.h ) not the source one (CustBase.cpp ).
-----------------------------------------------
ytubis wrote: LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16
Debug/ZCodeProjectWin.exe : fatal error LNK1120: 1 unresolved externals
This one, I think, states that you have choosen the wrong type of project (you should choose Console Application ).
Hope that helps.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
How do I keep an application always on top? just like Winamp does.
*
|
|
|
|
|
Call SetWindowPos[^] onto your window, with the hWndInsertAfter parameter set to HWND_TOPMOST .
|
|
|
|
|
It brings the window to the top, but it's not permanent. It goes back when you click on another window. It should be on top all the time. May be like "System modal".
*
|
|
|
|
|