Hi Igor and eveyone
I have been playing round with SendMessage(). In [Q2] in the program below,
SendMessage(subhWnd,WM_LBUTTONUP,0,0) invokes WM_LBUTTONUP twice in the
sub window. Three times in the beginning, when I click on the main menu!
What have I misunderstood? I apologise for listing entire lengthy program.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//In resource.h, add the following manually and put it in Solution
//Explorer or test:
#define IDD_MYDIALOG 101
#define IDC_EDIT 102
//In test.rc (resource script - in Solution Explorer or test: create the
//resource file test.rc manually), add the following:
#include <windows.h>
#include "resource.h"
IDD_MYDIALOG DIALOG 0, 0, 400, 200 //Left, Top, Width, Height in dialog
//units depended on font size
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog Title"
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_EDIT, 10, 10, 100, 12, ES_AUTOHSCROLL
PUSHBUTTON "OK", IDOK , 120, 10, 50, 12
END
//test.cpp
#include "stdafx.h"
#include <iostream>
using namespace std;
#include <windows.h>
#include "resource.h"
HWND hWnd=NULL;//main window
HWND subhWnd=NULL;//sub window
int queen=0; int king=0;
void GetText(HWND hCtrl) {
int len = GetWindowTextLength( hCtrl );
if(len > 0) {
char* buf;
buf = (char*)new LPWSTR[len+1];// (char*) GlobalAlloc(GPTR, len + 1);
GetWindowText (hCtrl, (LPWSTR)buf, len + 1);
MessageBox (NULL, (LPWSTR)buf, L"YOU ENTERED:", MB_ICONERROR |
MB_OK | MB_TOPMOST);
delete []buf;
//GlobalFree ((HANDLE)buf);
}//if
}
BOOL CALLBACK DlgProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam) {
//hDlg of the dialog on the the main window receiving Message, i.e.
//IDD_MYDIALOG dialog.
switch(Message) {
case WM_INITDIALOG: {
//SET TEXT.
//HWND hCtrl = GetDlgItem(hDlg, IDC_EDIT); //Get Control Handle.
//SetWindowText(hCtrl, L"This is a string"); //Set Text.
SetDlgItemText(hDlg, IDC_EDIT,L"This is a string");//Instead above two lines.
return TRUE;
}
case WM_CLOSE: {
EndDialog(hDlg,true);
return TRUE;
}
case WM_COMMAND: {
switch(LOWORD(wParam)) {
case IDC_EDIT: { //working on the edit box IDC_EDIT.
//ShowWindow(hWnd, SW_SHOW);
king=300;
cout<<"SendMessage(LBUTTONUP)\n";//[Q1] Prints twice?
SendMessage(subhWnd,WM_LBUTTONUP,0,0); //[Q2]Sends WM_LBUTTOMUP twice?
return FALSE;
} //IDC_EDIT
case IDOK: {
//SendMessage(subhWnd,WM_PAINT,0,0);
//GET TEXT.
HWND hCtrl = GetDlgItem(hDlg, IDC_EDIT);//hCtrl for the edit box IDC_EDIT
//ShowWindow(subhWnd, SW_HIDE);
GetText(hCtrl);
return 0;//TRUE;
}
} //switch(LOWORD(wParam))
return FALSE;
}//case:WM_COMMAND
}//switch(Message)
return FALSE;
}
static bool once=true; //for main window
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) {
//hwnd for the window receiving msg, i.e. the top/first window by CreateWindow().
switch(msg) {
case WM_LBUTTONUP: //Tap the touch pad twice.
if (once)DialogBox(/*GetModuleHandle(NULL),*/0,MAKEINTRESOURCE(IDD_MYDIALOG),hwnd,DlgProc);
once=false;//DialogBox() disables the owner window hwnd of the dialog (to be created).
GetText(hwnd);//After Dialog box terminate
return 0;
case WM_DESTROY:
PostQuitMessage(0); //Add WM_QUIT to message queue.
return 0;
}
//CALL DEFAULT WINDOW PROCEDURE.----------------------------------
return DefWindowProc(hwnd, msg, wParam, lParam);
}
//•write the winmain function and the call back function like you do in a win32 windows project
const TCHAR* g_szWINDOW_TITLE = L"Window with Console log";
const TCHAR* g_szCLASS_NAME = L"MyClass";
const TCHAR* g_subWINDOW_TITLE = L"Sub Window with Console log";
const TCHAR* g_subCLASS_NAME = L"MySubClass";
//BUTTON *g_button;
// Function for our sub Window Proc
LRESULT CALLBACK SubWindowPro(HWND _hWnd, unsigned int _unMsg, WPARAM _wParam, LPARAM _lParam)
{
static int x=0;
switch (_unMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
//default:
case WM_LBUTTONUP://Click on the touchpad on the dialogue window.
{ cout<<"I am the king: "<<king<<" queen: "<<queen<<"\n";
king=666;
x=x+10;
cout<<"x = "<<x<<"\n";
InvalidateRect(_hWnd,NULL,FALSE);//Sends WM_PAINT when the update region is
//empty &there are no other messages in the app queue for that window.
//The update region is the portion of the window's client
//area that must be redrawn.
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
}
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc;
if (x<1){ps.rcPaint.left=(LONG)100;ps.rcPaint.top=(LONG)600;ps.rcPaint.right= (LONG)700;
ps.rcPaint.bottom=(LONG)10;}
hdc= BeginPaint(_hWnd, &ps);//BeginPaint() works only in WM_PAINT handler.
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+x));//Fills the rectangle in
//COLOR_WINDOW++x. Comment this & see the differernce.
//Uncommented, it is the same as 'InvalidateRect(_hWnd,NULL,TRUE)'.
TextOut(hdc, x ,x , L"2nd console", wcslen(L"2nd console"));
TextOut(hdc, x+100 ,x+100 , L"Chong is completed", wcslen(L"Chong is completed"));
EndPaint(_hWnd, &ps);
return 0;
}
//case IDOK: cout<<"Chong\n";
return 0;
}
return DefWindowProc(_hWnd, _unMsg, _wParam, _lParam);
}
int WINAPI wWinMain(HINSTANCE _hInstance, HINSTANCE _hPrevInstance,
LPTSTR _lpCmdLine, int _nCmdShow)
{
// Create a window structure for the main winodw
WNDCLASSEX wndEx;
wndEx.cbSize = sizeof(WNDCLASSEX);
wndEx.style = CS_HREDRAW | CS_VREDRAW;
//wndEx.lpfnWndProc = MainWindowPro;
wndEx.lpfnWndProc = WndProc;//for the dialog in the main window
wndEx.cbClsExtra = 0;
wndEx.cbWndExtra = 0;
wndEx.hInstance = _hInstance;
wndEx.hbrBackground = HBRUSH(COLOR_WINDOW + 1);
wndEx.lpszMenuName = NULL;
wndEx.hCursor = LoadCursor(NULL, IDC_ARROW);
wndEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndEx.lpszClassName = g_szCLASS_NAME;
wndEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the structure
RegisterClassEx(&wndEx);
// Create the main window
//hWnd = CreateWindowEx(WS_EX_APPWINDOW, g_szCLASS_NAME, g_szWINDOW_TITLE, WS_OVERLAPPEDWINDOW,
hWnd = CreateWindowEx(BS_3STATE, g_szCLASS_NAME, g_szWINDOW_TITLE, WS_OVERLAPPEDWINDOW,
(GetSystemMetrics(SM_CXSCREEN) / 2) - 400, (GetSystemMetrics(SM_CYSCREEN) / 2) - 300,
800, 600, nullptr, nullptr, _hInstance, nullptr);
if (hWnd == nullptr)
return -1;
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
// Create a window structure for the subwindow
WNDCLASSEX wndEx1;
wndEx1.cbSize = sizeof(WNDCLASSEX);
wndEx1.style = CS_HREDRAW | CS_VREDRAW;
// wndEx.lpfnWndProc = WindowProc;
wndEx1.lpfnWndProc = SubWindowPro;//sub window callback procedure.
wndEx1.cbClsExtra = 0;
wndEx1.cbWndExtra = 0;
wndEx1.hInstance = _hInstance;
wndEx1.hbrBackground = HBRUSH(COLOR_WINDOW + 1);
wndEx1.lpszMenuName = NULL;
wndEx1.hCursor = LoadCursor(NULL, IDC_ARROW);
wndEx1.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndEx1.lpszClassName = g_subCLASS_NAME;
wndEx1.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the structure
RegisterClassEx(&wndEx1);
// Create the window
//HWND subhWnd = NULL;//sub window.
subhWnd = CreateWindowEx(BS_3STATE, g_subCLASS_NAME, g_subWINDOW_TITLE, WS_OVERLAPPEDWINDOW,
(GetSystemMetrics(SM_CXSCREEN) / 2) - 300, (GetSystemMetrics(SM_CYSCREEN) / 2) - 200,
800, 600, nullptr, nullptr, _hInstance, nullptr);
if (subhWnd == nullptr)
return -1;
ShowWindow(subhWnd, SW_SHOWDEFAULT);
UpdateWindow(subhWnd);
MSG Msg;
while (true)
{
if (PeekMessage(&Msg, nullptr, 0, 0, PM_REMOVE))
{
if (Msg.message == WM_QUIT)
break;
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
//UnregisterClass(g_szWINDOW_TITLE, _hInstance);
UnregisterClass(g_szCLASS_NAME, _hInstance);
return 0;
};
int main(int argc, _TCHAR* argv[])
{
std::cout << "hello !!!";
wWinMain(::GetModuleHandle(NULL), NULL, NULL, SW_SHOWDEFAULT);
return 0;
}
Regards
Chong