|
Here is the short version: I have several classes, some templatized, that inherit from a common abstract base class. I want a way to check at run-time whether a pointer points to an object that inherits from the base class. Because I am using templates, I can't use the MFC IsKindOf().
I have several templatized classes that derive from an abstract base class, following the GoF Bridge pattern:
<br />
class AbstractDataItem<br />
{<br />
public:<br />
virtual ~AbstractDataItem() = 0;
};<br />
<br />
template<class Ty_> class ConcreteDataItem :<br />
public AbstractDataItem<br />
{<br />
public:<br />
virtual ~ConcreteDataItem();<br />
}<br />
<br />
class SpectrogramDataItem :<br />
public AbstractDataItem<br />
{<br />
public:<br />
virtual ~SpectrogramDataItem();<br />
}<br />
This summarizes the inheritance structure. Now I have a pointer and I want to check whether it points to something that inherits from AbstractDataItem. Because I am using templates, I cannot have AbstractDataItem inherit from CObject and use DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC and use MFC's IsKindOf().
The standard C++ typeid() function seems only to give me the top-level class and does not provide a way to check forinheritance. I could try dynamic_cast<> and catch exceptions, but there is an awful lot of overhead in that and it's ugly.
I could exhaustively check the typeid against a list of derived classes, but that would kill my ability to subclass existing classes in the hierarchy---I'd have to go back in and rewrite my inheritance-testing list.
It would be nice if I didn't have to completely rewrite my own version of MFC's CObject and CRuntimeClass to handle templates and namespaces.
|
|
|
|
|
Basically, dynamic_cast<> is your best bet.
|
|
|
|
|
Hi,
I have tried to connect to SQL Server database using ASO , I used the example from the MSDN but faced a problem with the name spaces can some one give me the detailed sequence of operations to connect to a database and retrieve data.
Thank
Kalyan
|
|
|
|
|
Hello!
I'm NO expert but I seem to recall that you need to import ado like this:
In stdafx.h
#import "c:\program files\common files\system\ado\msado15.dll" no_namespaces rename("EOF" "adoEOF")
// Mike
|
|
|
|
|
I have made a program that has a toolbar. When I run the program on my computer it runs normally but when I try to execute it on other pc a GPF occurs (fail on comctl32.dll) and the program shutdowns.
My os is Win 95 C and I use the compiler borland 5.5.
Any possible solution is welcome.
|
|
|
|
|
Sounds like the other machine has an older version of COMCTL32.DLL than on your dev machine. Various structures have changed in the revs of the common controls. Grab a COMCTL32 updater from MS and install that on the other machine.
|
|
|
|
|
Where in the MFC libraries or a source code archive can I find the equivalents to FileListBox,
DirListBox and DriveListBox?
|
|
|
|
|
What's wrong with the follwing code?
//Header file...
class CSubclassWnd : public CWnd
{
private:
HWND m_hwnd;
BOOL m_bIsSubclassed;
static WNDPROC m_oldWndProc;
public:
CSubclassWnd();
~CSubclassWnd();
BOOL CaptureWindow(HWND hWnd);
void ReleaseWindow();
inline BOOL IsSubclassed(){return m_bIsSubclassed;}
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
};
//Implementation file...
CSubclassWnd::CSubclassWnd()
{
m_bIsSubclassed=FALSE;
}
CSubclassWnd::~CSubclassWnd()
{
ReleaseWindow();
}
BOOL CSubclassWnd::CaptureWindow(HWND hWnd)
{
m_oldWndProc=(WNDPROC)::SetWindowLong(hWnd, GWL_WNDPROC, (LONG)WindowProc);
if (m_oldWndProc!=0)
{
m_hwnd=hWnd;
m_bIsSubclassed=TRUE;
return TRUE;
}
return FALSE;
}
void CSubclassWnd::ReleaseWindow()
{
if (m_bIsSubclassed)
{
m_bIsSubclassed=FALSE;
::SetWindowLong(m_hwnd, GWL_WNDPROC, (LONG)m_oldWndProc);
}
}
LRESULT CALLBACK CSubclassWnd::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message==WM_MOVING)
MessageBeep((UINT)-1);
return ::CallWindowProc(m_oldWndProc, hWnd, message, wParam, lParam);
}
When I compile the above, I get the following error:
error LNK2001: unresolved external symbol "private: static long (__stdcall* CSubclassWnd::m_oldWndProc)(struct HWND__ *,unsigned int,unsigned int,long)" (?m_oldWndProc@CSubclassWnd@@0P6GJPAUHWND__@@IIJ@ZA)
Any ideas? Thanks in advance.
|
|
|
|
|
m_oldWndProc is a static member and needs to be initialized outside the class definition, typically in the .cpp file.
Something like this:
WNDPROC CSubclassWnd::m_oldWndProc = NULL;
|
|
|
|
|
Thanks for the tip. I'll give it a whirl.
|
|
|
|
|
|
Have you subclassed windows without using MFC? If so, then you probably know more than I do, but based on my understanding of MFC, most of what you are doing is unnecessary with MFC.
What is the value of having m_hwnd in your CSubclassWnd class? I guess that since it is spelled differently from CWnd::m_hWnd, it is less likely to be confusing, but it seems unnecessary to me.
|
|
|
|
|
I'm not sure that there WAS a purpose. When I wrote the class, I did so very quickly, and honestly didn't give it much thought other than the subclassing work. I've actually done a lot of subclassing using C and the Win32 API, which is not that difficult; nothing is wrapped. However, I've never really tried to subclass from within a class structure, and therein lies my confusion.
Apparently, you have to declare your subclass function as 'static' if you intend to use it for subclassing. The problem with that is that functions declared as static remove the 'this' pointer, and they can only reference variables and methods that are also declared as 'static'. Not acceptable in my app, because I use the 'this' pointer in some of my methods.
So, what I actually did was deleted the CSubclassWnd class, then added the subclass function and OldWndProc variable to my classes .cpp file, outside of any classes (before any 'class' keywords). Sure, that makes them global, but it works, and I have the functionality that I need.
Thanks all for the help. I'll keep this all in mind for future projects.
|
|
|
|
|
Yes, you have to declare your subclass function as 'static' if you intend to use it for subclassing. It is the fact that functions declared as static remove the 'this' pointer that makes it possible for Windows to call a function in your class. Think about what Windows is doing when it calls your callback function. Windows calls your function with certain parameters; a "this" pointer is not one of the parameters. Think about that and I think you will realize why the function must be static.
Whatever functionality that you need, almost for sure there is an easier way to do it if you do it the MFC way instead of trying to get around MFC.
|
|
|
|
|
How to add a ToolBar on a dialog form...
please help me...
or. mabe how to add a dialog as a normal MDI program..
|
|
|
|
|
Hi All,
Is it possible to set the host type for
CFtpConnection ?
The problem is:
the remote system has diffrent OSs.
I need to connect MVS part, but the default host
type seems to be UNIX.
P.S. I would prefer not to use CSocket and other low-level
stuff like that.
Yours sincerely,
Alexander Chaikin
|
|
|
|
|
Alexander,
I'm not quite sure what difficulty you are having. The FTP protocol specifies that all devices, client and server, must adhere to very strict communication standards. These standards among other things specify that all terminal interaction over the control channel must be in NVT (Network virtual terminal), and things like directory listings should be displayed in a format similar to Unix.
So, that said, your MVS connection shouldn't affect your ability to upload and download files, or display directories. If you are of course downloading files, they could very well be unreadable.
Could you explain for me what you're getting?
|
|
|
|
|
Alex,
I got your response via email, but it doesn't seem to be on the board (bug Chris/Uwe)?
It sounded from the tone of your email that you'd found a solution; have you?
Even though MVS supports a different file naming convention, the FTP server implementation is still responsible to display directories in the standard FTP (Unix) format. The FTP server under Windows has the ability to display directories in MS-DOS or Unix format, but if you set it to anything other than Unix, none of the Windows (automated) ftp programs will work correctly.
So, I think you've got two choices. a) try and figure out how to get your MVS system to display directories the correct way (there may be a command you can enter), or b) get some FTP sourcecode and start making some customizations.
I think everyone knows that we sell the Dundas TCP/IP source code, but if you are not worried about licensing issues, warranties, etc., you might have a look at some of the free code available here and at CodeGuru.
Someone correct me if I'm wrong, but I think PJ's ftp stuff is written to use the Wininet stuff (which CFTPConnection wraps).
Hope that helps.
|
|
|
|
|
Hi!
i'm loking to unrar archives in my own program but i don't know how to do, i downloaded somes files from rarsoft.com but it seems to miss rar.lib.
who can help me ?
|
|
|
|
|
I have been using PowerArchiver 2000. It is a knock off of Winzip and can handle numerous file types.
|
|
|
|
|
Hi
I've created one mfc based application that hosts microsoft's WebBrowser control on windows 98. but when i try to run it, it hangs. i did some research and found out that if i have internet explorer version 5.5 on win 98, then it works fine but if you don't have ie 5.5, then it hangs.
Is there any way i can get an old version of MS WebBrowser control so that it doesn't require ie 5.5? Is there any other way i fix this problem.
I would really appreciate ur help.
Thanks
Parvesh
|
|
|
|
|
Hi, I have a few questions about Multi-threading with MFC.
1. With the function you supply in the first parameter of AfxBeginThread, - the new thread calls this function- if you have multiple threads calling this function, is a new instance of the function created or is it used by all threads? ie
AfxBeginThread( UpdateClients, this )
If you create 3 threads, do these 3 threads all share
the same instance of UpdateClients? Wouldn't make a lot
of sense if they did...but just curious.
2. I'm creating a client/server application which has
basic transfer/sending capabilities. I was intending to create a seperate thread for each dialog box used to indicate how much a file has been sent/receive. What is the best method for doing this? Should I use CWinThread?
The tutorials for using GUI threads confused me more.
Thanks for your Help
|
|
|
|
|
Andrew:
A couple of pointers:
1. A function doesn't really have an "instance" in the way a variable does. All threads calling a function are invoking the same code -- Windows doesn't keep multiple copies of the code in memory. Each thread does have its own call stack -- which tracks the state of the program-execution for that thread. Lastly, note that if the function has a static variable declared within, that variable will be shared between threads unless it is set to use thread-local storage.
2. You _can_ have your dialogs running on other threads, and CWinThread is a fine way to achieve this. However, I would consider keeping the GUI elements on the main thread and placing your processing code on another. In this case, your dialogs can simply be modeless and query the worker thread they are associated with for a periodic status update. Either way will work, and it's debatable what is a "better" solution. Personally, I like to keep the GUI on one thread, esp. if I'm using MFC.
Regards,
Nick Hodapp
|
|
|
|
|
Hello,
I am sorry to disturb you too much but i am really confused about the system-wide hooks. I am now using a DLL to catch all keyboard events, as Michael Dunn said. But again it works only with my program. Here is the source code:
<br />
*********************SystemHook.h**********************<br />
#ifdef SYSTEMHOOK_EXPORTS<br />
#define SYSTEMHOOK_API __declspec(dllexport)<br />
#else<br />
#define SYSTEMHOOK_API __declspec(dllimport)<br />
#endif<br />
<br />
class SYSTEMHOOK_API CSystemHook {<br />
public:<br />
CSystemHook(void);<br />
};<br />
SYSTEMHOOK_API LRESULT CALLBACK KeyboardProc(int code,WPARAM wParam,LPARAM lParam);<br />
SYSTEMHOOK_API int WINAPI InstallHook (HWND hWnd, BOOL bCode );<br />
*******************************************************<br />
<br />
*********************SystemHook.cpp**********************<br />
#include "stdafx.h"<br />
#include "SystemHook.h"<br />
<br />
#define ID_CMD_KEYPRESSED WM_USER+200<br />
<br />
HWND ghWndMain;
<br />
static HHOOK hHook;
static BOOL bHookInstalled;
<br />
HINSTANCE ghDLLInst;
<br />
BOOL APIENTRY DllMain( HANDLE hModule, <br />
DWORD ul_reason_for_call, <br />
LPVOID lpReserved<br />
)<br />
{<br />
switch (ul_reason_for_call)<br />
{<br />
case DLL_PROCESS_ATTACH:<br />
case DLL_THREAD_ATTACH:<br />
case DLL_THREAD_DETACH:<br />
case DLL_PROCESS_DETACH:<br />
break;<br />
}<br />
ghDLLInst=(HINSTANCE)hModule;<br />
return TRUE;<br />
}<br />
<br />
CSystemHook::CSystemHook()<br />
{ <br />
return; <br />
}<br />
<br />
SYSTEMHOOK_API LRESULT CALLBACK KeyboardProc(<br />
int code,
WPARAM wParam,
LPARAM lParam)
{<br />
if ( code >= 0 ) <br />
{ <br />
if (GetKeyState(VK_SHIFT) < 0 && GetKeyState(VK_CONTROL) < 0) <br />
{ <br />
switch (wParam) <br />
{ <br />
case VK_F9:<br />
if (HIWORD(lParam) & 0x8000) <br />
PostMessage(ghWndMain, WM_COMMAND, ID_CMD_KEYPRESSED, 0L);<br />
return 1;<br />
} <br />
}<br />
}<br />
return (int)CallNextHookEx(hHook, code, wParam, lParam); <br />
}<br />
<br />
SYSTEMHOOK_API int WINAPI InstallHook (HWND hWnd, BOOL bCode )<br />
{ <br />
int nReturn = 1;<br />
ghWndMain = hWnd;
<br />
if (bCode == bHookInstalled) <br />
return 0; <br />
<br />
if (bCode) <br />
{ <br />
hHook=(HHOOK)SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,ghDLLInst,0); <br />
if (!hHook) <br />
return 0; <br />
bHookInstalled = TRUE; <br />
} <br />
else <br />
{ <br />
nReturn = UnhookWindowsHookEx(hHook); <br />
bHookInstalled = FALSE; <br />
} <br />
return nReturn; <br />
}<br />
*******************************************************<br />
Then in my main view:
<br />
void CWinSchedulerView::OnInitialUpdate() <br />
{<br />
CFormView::OnInitialUpdate();<br />
InstallHook(m_hWnd,TRUE);<br />
}<br />
void CWinSchedulerView::OnDestroy() <br />
{<br />
CFormView::OnDestroy();<br />
InstallHook(m_hWnd,FALSE);<br />
}<br />
<br />
BOOL CWinSchedulerView::OnCommand(WPARAM wParam, LPARAM lParam) <br />
{<br />
if(wParam==ID_CMD_KEYPRESSED)<br />
MessageBox("Ctrl+Shift+F9");<br />
<br />
return CFormView::OnCommand(wParam, lParam);<br />
}<br />
This works only on my window.If i press ctrl+shift+f9 on another window, it does not work.
Thanks for any helps in advance.
Mustafa Demirhan
|
|
|
|
|
At least shared data should be in a shared/readable/writeable section. Following a working code sample.
|
|
|
|
|