Solved

How do i recieve WM_INITDIALOG from a created button ?

Posted on 2002-05-05
24
622 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 11
  • 8
  • 2
  • +2
24 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 6990718
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
ID: 6990730
Ooops, "Beg my pardon" should of course be "Beg your pardon" .o)
0
 
LVL 3

Expert Comment

by:GGRUNDY
ID: 6990869
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:andla
ID: 6991730
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
ID: 6992468
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
ID: 6993181
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
ID: 6993197
Sorry for above but right will be
WNDPROC OldProc=(WNDPROC)SetWindowLong( MyWindow, GWL_WNDPROC,
(DWORD)HookProc );
0
 
LVL 1

Author Comment

by:andla
ID: 6993459
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
ID: 6993488
Then look for CWinApp::PreTranslateMessage
0
 
LVL 1

Author Comment

by:andla
ID: 6993594
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
ID: 6993597
C++ != MFC
0
 
LVL 1

Expert Comment

by:kosolobov
ID: 6993643
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
 
LVL 1

Expert Comment

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

Author Comment

by:andla
ID: 6993972
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
ID: 6993997
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
ID: 6994257
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
ID: 6995716
And C++ != Windows Programming
;-)
0
 
LVL 1

Author Comment

by:andla
ID: 6995917
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
ID: 6996095
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
ID: 6996303
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
ID: 6996390
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
ID: 6996414
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
ID: 6996440
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
ID: 6996529
Thank you.
Waiting for your questions :)
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Getting IP address 8 123
Android development question 2 108
MFC COM Server not showing  form 4 25
COM server issue 2 24
Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

734 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