简体   繁体   中英

WM_Quit message being sent when i click on textbox

so title says it all. i was thinking maybe because there are 81 textboxes it has somthing to do with layers but quite frankly i have no idea.. just started learning windows api like 2 days ago and ive been learning streight off the msdn library for functions.. i googled this problem multiple times and no luck so here i am. the help is much appreciated ^.^

// Win32Project9.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "Win32Project9.h"
#include "Resource.h"
#include <Windows.h>
#include <vector>
#include <cstring>

using namespace std;

HWND Hwnd;
HMENU hMenu;
HWND boxes[81];
int x, y;
vector<LPWSTR> BoxNum;


LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_COMMAND:
    switch (LOWORD(wParam))
    {
    case IDM_EXIT:
        PostQuitMessage(0);
        return 0;
    break;

    case ID_SOLVE:
        for (int i = 0; i < 81; i++)
        {
            GetWindowText(boxes[i], BoxNum[i], NULL);
        }
    break;
    }
break;
}

if (msg == WM_COMMAND)
{
    if (LOWORD(wParam) > 199 && LOWORD(wParam) < 281)
    {
        if (HIWORD(wParam) == EN_SETFOCUS | HIWORD(wParam) == EN_UPDATE)
        {
            return DefWindowProc(hwnd, msg, wParam, lParam);
        }
    }
}

else if (msg == WM_CLOSE)
{
    PostQuitMessage(0);
    return 0;
}

return DefWindowProc(hwnd, msg, wParam, lParam);
}

void DrawBoard()
{
x = 10;
y = 10;
int count = 0;

for (int i = 0; i < 81; i++)
{
    int BOX_ID = 200 + i;
    boxes[i] = CreateWindow(TEXT("Edit"), NULL, WS_CHILD | WS_BORDER | WS_VISIBLE, x, y, 20, 20, Hwnd, (HMENU)BOX_ID, NULL, NULL);

    x += 30;
    count++;

    if (count == 9)
    {
        y += 30;
        x = 10;
        count = 0;
    }
}
}

int WINAPI WinMain(HINSTANCE hInstance,
               HINSTANCE hPrevInstance,
               LPSTR lpCmdLine,
               int nCmdShow)
{   

//structure to hold window specs
WNDCLASSEX Wc;

//allocate memory for window class
ZeroMemory(&Wc, sizeof(WNDCLASSEX));

//fill in neccessary info
Wc.cbSize = sizeof(WNDCLASSEX);

Wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
Wc.hCursor = LoadCursor(hInstance, IDC_ARROW);
Wc.hInstance = hInstance;
Wc.lpfnWndProc = WindowProcedure;
Wc.lpszClassName = L"MyClass";
Wc.style = CS_HREDRAW | CS_VREDRAW;

//register class
RegisterClassEx(&Wc);

//load menu into handle
hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(ID_MENU));

//Create Window with class and create handle
Hwnd = CreateWindow(L"MyClass", L"Sudoku", WS_OVERLAPPEDWINDOW, 0, 0, 300, 340, NULL, hMenu, hInstance, NULL);

//DisplayWindow
ShowWindow(Hwnd, nCmdShow); 

DrawBoard();

//structure to hold input stream
MSG msg;

//listen for input
while(GetMessage(&msg, Hwnd, NULL, NULL))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

return 0;
}

also i read that wm_close is processed when i press the x button. well this message is being recieved even when i click the text boxes. and if you look at my case WM_Close.. i coded it to make a message box and give the user a chance to accept or not.... so when this happens after clicking on a text box i click no and another message box apperas asking again, i click no and it goes away but when i click the x button and i click no the window still dissapears .....

The problem is probably that WM_COMMAND is not handled properly.

The arguments received are as follows:

WORD code = HIWORD(wParam);
WORD id = LOWORD(lParam);

The problem is that code depends on the type of control you are using. For example, if it is a button it will be some of the BTN_* values, if it is an edit it will be EN_* and so on. But these values overlap badly, so you cannot use them in a single switch.

For example CBN_KILLFOCUS==4 , but also LBN_SETFOCUS==4 ... Also menu items will get here a 0 and accelerators a 1. By the way, BN_CLICKED==0 and it looks like no other notification message uses 0, so you can use the same IDs in menus and buttons and it will just work. And accelerators too, with a bit of care... BN_PAINT==1 , I think this one does not exist anymore, but you get the point...

Anyway, to your problem. My guess is that you have an EDIT that happens to have an ID equal to IDM_EXIT . Since you are not checking the HIWORD(wParam) you are quitting when you receive the EN_SETFOCUS on this control.

The solution is: First, always check both WORDs from wParam . Second, avoid collisions between menu options and ID controls, except maybe with buttons.

case WM_COMMAND:
    switch (LOWORD(wParam))

That isn't quite good enough. Edit controls also send WM_COMMAND messages to notify their parent window about stuff going on. Like EN_UPDATE whenever you type a character. Or EN_SETFOCUS when they get the focus, sounds like your case when you see this go wrong when you click on them. These notifications are wrapped in a WM_COMMAND message.

You must therefore pay attention to where the WM_COMMAND message came from. The LPARAM argument tells you. If IDM_EXIT comes from a menu item then you must verify that LPARAM is 0. Check the MSDN library for details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM