1

Lets say I have an MFC application with a button control on it. Is there a way to retrieve that function that OON_BN_CLICKED maps it to? I know CWnd has a GetDlgItem function which will return a pointer to a control. Is there a way to get the function the control is mapped to if I have this pointer?

I have found a method which I believe can be used to send a message to a Dialog item or control: CWnd::SendDlgItemMessage (http://msdn.microsoft.com/en-us/library/e2a6czt1.aspx), but Id' like to be able to know the possible messages.

Amre
  • 1,630
  • 8
  • 29
  • 41
  • Do you have source for the application with the control in question, or are you wanting to probe an external control? – mwigdahl Dec 23 '14 at 16:54

1 Answers1

0

In most circumstances, you know the messages you can send to a window. I strongly suspect you might be not taking the right path for your task. What are you trying to accomplish actually? I.e. what you are asking is uncommon, and the real task can most probably can be solved by other means.

Anyways. If you have a pointer to some MFC CWnd-derived object, it is still possible to 'reverse engineer' it's MFC message handlers defined in the class pointed by that CWnd*. MFC defines all message handlers in a map using BEGIM_MESSAGE_MAP/END_MESSAGE_MAP. What these macros actually do is, they define a virtual function called GetMessageMap() and a data array containing structures describing message mapping. So you can could use wnd->GetMessageMap() and then iterate over the mapped message handlers. Each entry contains information about the message handler, and the mapped function. Note that GetMessageMap is a protected function, so to access it from outside, you'll need a wrapper. Something like this:

struct Accessor : public CWnd
{
    // overwrite protected
    virtual const AFX_MSGMAP* GetMessageMap() const { return CWnd::GetMessageMap(); }
};

Accessor* msg_map_access = (Accessor*) window;
const AFX_MSGMAP* msg_map = msg_map_access->GetMessageMap();

const AFX_MSGMAP_ENTRY* entry = msg_map->lpEntries;
while (entry->nSig != AfxSig_end)
{
    /// do something with the entries
}

Again, this is not common practice; normally, you never do that. So it would be nice to hear the motivation why you need this.

Nikolay
  • 10,752
  • 2
  • 23
  • 51
  • This is exactly what I'm trying to do. The motivation behind it is there are applications out there that allow you to do this kind of thing, possibly giving the user access to something they should not have, even if the button was disabled. I'm writing an app that I can use to test, as I make changes to protect against it. – Amre Dec 23 '14 at 19:09
  • Hmm if you want to protect your code from modification (or external access) probably it would make more sense to use a software protector.. I mean, there are some tools on the market to protect programs, like Themida/WinLicense, Obsidium, etc. If you want that nobody can click the disabled button by sending messages, you just need to check in the message handler that operation is not allowed (in addition to disabling the button) – Nikolay Dec 23 '14 at 19:19