Solved

How do i recieve WM_INITDIALOG from a created button ?

Posted on 2002-05-05
24
603 Views
Last Modified: 2010-08-05
Hi! please help me.

I create a button dynamically and subclass it. I don't recieve any WM_INITDIALOG. What should i do ?

Regards
Andla.
0
Comment
Question by:andla
  • 11
  • 8
  • 2
  • +2
24 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Beg my pardon, but a button is not a dialog at all - so how is it supposed to receive that message?
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Ooops, "Beg my pardon" should of course be "Beg your pardon" .o)
0
 
LVL 3

Expert Comment

by:GGRUNDY
Comment Utility
Try "Add virtual function" to override PreSubclassWindow. When you are writing your own control subclass it is almost what WM_INITDIALOG is for a dialog.
(PS. Try your windows questions in the EE "Windows Progaming" forum.)
0
 
LVL 1

Author Comment

by:andla
Comment Utility
jkr>> You have recieved my pardon. ;-)

Sorry i suppose i meant WM_CREATE.
The funny thing is that if i use:
PostMessage(MyWindow,WM_INITDIALOG,0,0);
Then i recieve this in my callback function.
If i use WM_CREATE i don't. I suspect that the original procedure eats WM_CREATE so that my procedure don't get any piece. :-)


GGRUNDY>>Sorry i don't use MFC othewise this would probebly be what i want to do.


My approach to subclass a window is the following:

OldProc=(HWND)GetWindowLong( MyWindow,GWL_WNDPROC );
SetWindowLong( MyWindow, GWL_WNDPROC,
(DWORD)HookProc );

Regards
Andla
0
 
LVL 4

Expert Comment

by:mblat
Comment Utility
It is probably because WM_CREATE gets through BEFORE you actually subclass your window.  
Depending on what you want to do you can use other message,
for example WM_CTLCOLORBTN.  OF cause it gets called multiple times, but there are easy ways to avoid a this problem.

Hope it helps.
0
 
LVL 1

Expert Comment

by:kosolobov
Comment Utility
mblat it right.
Use your WM_CREATE code from Dialogs WM_INITDIALOG handler.

Also You can use just:
OldProc=(HWND)SetWindowLong( MyWindow, GWL_WNDPROC,
(DWORD)HookProc );

0
 
LVL 1

Expert Comment

by:kosolobov
Comment Utility
Sorry for above but right will be
WNDPROC OldProc=(WNDPROC)SetWindowLong( MyWindow, GWL_WNDPROC,
(DWORD)HookProc );
0
 
LVL 1

Author Comment

by:andla
Comment Utility
Ok i suppose i will have to live with sending a PostMessage with WM_INITDIALOG when i create a button. I wish there where a way to freeze the messages. Hmm i was just thinking maybe i can catch them in the first loop:

while(GetMessages(msg,0,0,0))
{
}

Don't know.

/Andla
0
 
LVL 1

Expert Comment

by:kosolobov
Comment Utility
Then look for CWinApp::PreTranslateMessage
0
 
LVL 1

Author Comment

by:andla
Comment Utility
Sorry once again i don't use MFC.
What would this be for a non MFC user ?

/Andreas
0
 
LVL 1

Author Comment

by:andla
Comment Utility
C++ != MFC
0
 
LVL 1

Expert Comment

by:kosolobov
Comment Utility
then you must have own message loop.
place inside that loop
if (msg==WM_CREATE && create_struct->hwndParent==dialog_handle )
{
// use GetDlgCtrlID to get control ID and
if (id == nButtonID) {...}
}

also - you might hook WM_NCCREATE to get button handle.
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 1

Expert Comment

by:kosolobov
Comment Utility
And C++ != Windows Programming
;-)
0
 
LVL 1

Author Comment

by:andla
Comment Utility
I will look into this later and se if can catch it. It's like catching a needle in a hay stack :-)

BTW I will try windows programming area in the future but if the response time is much longer I stick to the old gold mine.

/Andla
0
 
LVL 1

Expert Comment

by:kosolobov
Comment Utility
There are another way around your problem.
implement own button control (OCX, ActiveX) and place it insteed original button :)

As for me i'm rare guest in Windows Programming :)

WBR,
Petr.
0
 
LVL 4

Expert Comment

by:mblat
Comment Utility
Just a question:
what exectly do you need to do with your button? Why can't you do it in WM_CTLCOLORBTN?  
That would let you to create button with WM_CREATE?
0
 
LVL 1

Expert Comment

by:kosolobov
Comment Utility
And C++ != Windows Programming
;-)
0
 
LVL 1

Author Comment

by:andla
Comment Utility
I don't recieve WM_CTLCOLORBTN or WM_CREATE. What i want to do i implementing a scripting engine that create different controls. I had working scripting call for WM_LBUTTONDOWN WM_LBUTTONUP and so on but it failed for WM_CREATE and therefore if i had creation code for buttons in WM_CREATE it was never called. Therefore i can live with posting a WM_INITDIALOG but it would be intresting to know new programming stuff to catch WM_CREATE. It is sad that i can't find any similar functions that you posted as MFC solutions that would work on simple Win32.

Regards
Andla
0
 
LVL 1

Accepted Solution

by:
kosolobov earned 50 total points
Comment Utility
1. The best way, in my opinion, is to create custom control(ActiveX) which will subclass button control and place it on dialog.

2. Another way is to insert in you plain Win32 application message loop several lines of code:

BOOL bRet;
MSG msg;
while( (bRet = ::GetMessage( &msg, NULL, 0, 0 )) != 0)
{
    if (bRet == -1)
    {
        // handle the error and possibly exit
    }
    else
    {
// hear you can intercept WM_CREATE for dialog controls
if (msg.message == WM_CREATE)
{
CREATESTRUCT* pcs = (CREATESTRUCT*)msg.lParam;
if (pcs->hwndParent == hMyDialog && ::GetDlgCtrlID(msg.hwnd) == MY_BUTTON_ID)
{
// handle your button WM_CREATE here
}
}
// process standard handler
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
    }
}

3. the last one is to hook apllication message loop, like:
HHOOK hHook = ::SetWindowsHookEx(WH_CALLWNDPROC, MyHookFunction, NULL, ::GetCurrentThreadId());
And process in MyHookFunction WM_CREATE message exactly like in method 2.

I suppose this will be  enough. :)
0
 
LVL 1

Author Comment

by:andla
Comment Utility
Number 3 is intresting and number 1 if 3 doesn't work.
I think I have tested number 2:

while( GetMessage( &msg, NULL, 0, 0 )  )
{
     if(msg.message==WM_CTLCOLORBTN)
     {
          Sleep(0);//This is not recieved.
     }
     if(msg.message==WM_CREATE)
     {
          Sleep(0);//This is not recieved either.
     }
     if( IsDialogMessage( hWnd, &msg ) )
          continue;                
     TranslateMessage( &msg );  
     DispatchMessage( &msg );
}

Don't know if I can do number 2 if I first use number 3. If I use number 3 would that have a similar effect like:

OldProc=(HWND)SetWindowLong( MyWindow, GWL_WNDPROC,
(DWORD)HookProc );

but it would maybe listen to all new buttons created in the thread. Don't know I'm pretty new to number 3 approach.

Regards
Andla
0
 
LVL 1

Expert Comment

by:kosolobov
Comment Utility
2nd approach will not work for reason that GetMessage work only with Posted messages and WM_CREATE is Sended.
sorry about that :)

In 3d approach you can UnhookWindowsHook after receiving needed WM_CREATE.
Also this Hook will work for every SendMessage()in your application, sended by application itself as well by system.
Also try to use WM_NCCREATE in pp 3.

0
 
LVL 1

Expert Comment

by:kosolobov
Comment Utility
I done a test
1. generated with VC6.0 win32 "Hello World" project
2. and changed functions like:

HHOOK hHook;
LRESULT CALLBACK MyHookFunction(
  int nCode,      // hook code
  WPARAM wParam,  // current-process flag
  LPARAM lParam   // message data
)
{
     CWPSTRUCT* pcw = (CWPSTRUCT*)lParam;
     if (pcw->message == WM_CREATE &&
          ::GetDlgCtrlID(pcw->hwnd) == IDOK)
     {
          UnhookWindowsHookEx(hHook);
          MessageBox(NULL, "OK button created", "WM_CREATE", MB_OK);
          // more processing here
     }
     return CallNextHookEx(hHook, nCode, wParam, lParam);
}

//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND     - process the application menu
//  WM_PAINT     - Paint the main window
//  WM_DESTROY     - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     int wmId, wmEvent;
     PAINTSTRUCT ps;
     HDC hdc;
     TCHAR szHello[MAX_LOADSTRING];
     LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

     switch (message)
     {
          case WM_COMMAND:
               wmId    = LOWORD(wParam);
               wmEvent = HIWORD(wParam);
               // Parse the menu selections:
               switch (wmId)
               {
                    case IDM_ABOUT:
// here
                         hHook = ::SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)MyHookFunction, NULL, ::GetCurrentThreadId());
                       DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
                       break;
                    case IDM_EXIT:
                       DestroyWindow(hWnd);
                       break;
                    default:
                       return DefWindowProc(hWnd, message, wParam, lParam);
               }
               break;
          case WM_PAINT:
               hdc = BeginPaint(hWnd, &ps);
               // TODO: Add any drawing code here...
               RECT rt;
               GetClientRect(hWnd, &rt);
               DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
               EndPaint(hWnd, &ps);
               break;
          case WM_DESTROY:
               PostQuitMessage(0);
               break;
          default:
               return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}
0
 
LVL 1

Author Comment

by:andla
Comment Utility
This is maybe how MFC uses PreSubclassWindow ?
This looks intresting. Thanks for your help kosolobov.
I will maybe fall into further problem before i actually make this work. Stay put here if you want. Either way i appreciate your help.

Best regards
Andla
0
 
LVL 1

Expert Comment

by:kosolobov
Comment Utility
Thank you.
Waiting for your questions :)
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now