Solved

How do i recieve WM_INITDIALOG from a created button ?

Posted on 2002-05-05
24
608 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
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
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 
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

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

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

This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
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 member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

813 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

12 Experts available now in Live!

Get 1:1 Help Now