Thread: Window Button

  1. #1
    Registered User sean345's Avatar
    Join Date
    Mar 2002
    Posts
    346

    Window Button

    I have created a window that has 2 edit controls and 1 push button. One edit control is a multiline edit control and the other is a single line edit control. I would like to make it so that when the user is typing in text in the single line edit control and pushes enter, the push button is pressed. When I press enter it seems nothing happens, even if I am not entering text in the single line edit control.

    By the way I am not using a dialog box, its a regular window.

    Does anyone know how to do this? Thanks.

    - Sean
    Last edited by sean345; 07-06-2002 at 03:10 PM.
    If cities were built like software is built, the first woodpecker to come along would level civilization.
    Black Frog Studios

  2. #2
    Registered User
    Join Date
    May 2002
    Posts
    317
    Are you using MFC or WINAPI?

    Its important to understand that edit controls and buttons are all child windows and have to have the input focus to accept keyboard input. Please answer the above question and we will continue the discussion, their are a couple ways to proceed.

  3. #3
    Registered User sean345's Avatar
    Join Date
    Mar 2002
    Posts
    346
    I am using Win API. I know that in a dialog window when you press enter it is just like pressing the default button. I am trying to do the same thing here only I am not using a dialog window.

    - Sean
    If cities were built like software is built, the first woodpecker to come along would level civilization.
    Black Frog Studios

  4. #4
    Registered User
    Join Date
    May 2002
    Posts
    317
    Thats because dialog boxes send the input focus to the default button by default. One way to do this is have your main window check for the WM_KILLFOCUS message and upon recieving that message place itself back in focus by using SetFocus(hwnd) (handle to main window). Then check the message queue for the enter key, and if pressed send message to button, if not send message to text controls. Note, you will have to keep track of what child window has the input focus.

    Edit:

    Out of curtousy to the user, I would also through in a check to ensure the mouse is within your window before immediately resetting focus to your program.
    Last edited by Traveller; 07-06-2002 at 04:49 PM.

  5. #5
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    If you are using a standard SDK app, you can try using SetWindowLong(), this can add another Window Procedure to sit on top of the edit control procedure provided by the framework....then use this to read the WM_KEYDOWN & WM_KEYUP and filter for VK_RETURN....then do whatever processing applicable.....

    If you are using MFC, the derive a class from CEdit, add the extra code and use it instead

  6. #6
    Registered User sean345's Avatar
    Join Date
    Mar 2002
    Posts
    346
    Traveller, I have set the focus to the button and then tried hitting enter, but it is not being pressed. I have then tried clicking on it to make sure it is working and then again tried hitting enter and it still will not work.

    Fordy, I have been looking up some things on subclassing in Petrolds book. Can you give me a quick example using the edit control because Petrold uses a different control and does something different. I am using the Win API.

    Currently, what I have done is edit my WinMain message loop like this:
    Code:
    while(GetMessage(&Msg, NULL, 0, 0) > 0){
    		if(Msg.message==WM_KEYDOWN&&LOWORD(Msg.wParam)==VK_RETURN){
    			SendMessage(hButtonTalk, BM_CLICK, 0, 0);
    			continue;
    		}
    		TranslateMessage(&Msg);
    		DispatchMessage(&Msg);
    	}
    The reason I added the continue in there is because the single line edit control was making the default error sound when I pressed enter. It seems to work, but I was wondering if there was a better way to do it. Thanks.

    - Sean
    If cities were built like software is built, the first woodpecker to come along would level civilization.
    Black Frog Studios

  7. #7
    Registered User
    Join Date
    May 2002
    Posts
    317
    Would you mind posting your code?

  8. #8
    Registered User sean345's Avatar
    Join Date
    Mar 2002
    Posts
    346
    This is the main source file. There are some other header files as well.
    Code:
    #include <windows.h>
    #include <string.h>
    #include <stdio.h>
    #include <merlin.h>
    
    #include "Global.h"
    #include "Main.h"
    #include "Menu.h"
    
    #include "Turingres.h"
    
    HINSTANCE ghInstance = NULL;
    HWND hwndMain = NULL;
    LPSTR gClassName = "TurningMachineClass";
    HWND hEditLog = NULL;
    HWND hEditInput = NULL;
    HWND hButtonTalk = NULL;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
    	MSG Msg;
    
    	ghInstance = hInstance;
    
    	if(RegisterWindow()==FAILURE){
    		return 1;
    	}
    
    	if(CreateMainWindow(nCmdShow)==FAILURE){
    		return 1;
    	}
    
    	while(GetMessage(&Msg, NULL, 0, 0) > 0){
    		if(Msg.message==WM_KEYDOWN&&LOWORD(Msg.wParam)==VK_RETURN){
    			SendMessage(hButtonTalk, BM_CLICK, 0, 0);
    			continue;
    		}
    		TranslateMessage(&Msg);
    		DispatchMessage(&Msg);
    	}
    
    	UnregisterClass(gClassName, ghInstance);
    	return Msg.wParam;
    }
    
    int static RegisterWindow(void){
    	InitCommonControls();
    
    	WNDCLASSEX wc;
    
    	wc.cbSize 			= sizeof(WNDCLASSEX);
    	wc.style 			= CS_VREDRAW | CS_HREDRAW;
    	wc.lpfnWndProc 		= WndMainProc;
    	wc.cbClsExtra		= 0;
    	wc.cbWndExtra		= 0;
    	wc.hInstance		= ghInstance;
    	wc.hIcon			= LoadIcon(NULL, IDI_QUESTION);
    	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);
    	wc.hbrBackground	= (HBRUSH)(COLOR_WINDOW + 11);
    	wc.lpszMenuName		= NULL;
    	wc.lpszClassName	= gClassName;
    	wc.hIconSm 			= NULL;
    
    	if(RegisterClassEx(&wc)==0){
    		ERRBOX(ERR_TITLE, ERR_REG);
    		return FAILURE;
    	}
    
    	return SUCCESS;
    }
    
    int static CreateMainWindow(int nCmdShow){
    	hwndMain = CreateWindowEx(WS_EX_CLIENTEDGE,
    							gClassName, WND_TITLE,
    							WS_OVERLAPPEDWINDOW,
    							CW_USEDEFAULT, CW_USEDEFAULT,
    							WND_WIDTH, WND_HEIGHT,
    							NULL, NULL, ghInstance, NULL);
    	if(hwndMain == NULL){
    		ERRBOX(ERR_TITLE, ERR_WND);
    		return FAILURE;
    	}
    
    	ShowWindow(hwndMain, nCmdShow);
    	UpdateWindow(hwndMain);
    
    	return SUCCESS;
    }
    
    LRESULT CALLBACK WndMainProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
    	switch(msg)
    	{
    		case WM_CREATE:
    			CreateControls(hwnd);
    			CreateMenus(hwnd);
    			break;
    		case WM_CLOSE:
    			CloseProgram(hwnd);
    			break;
    		case WM_SIZE:
    			ResizeWindow(hwnd);
    			break;
    		case WM_SETFOCUS:
    			SetFocus(hEditInput);
    			break;
    		case WM_COMMAND:
    			switch(LOWORD(wParam)){
    				case BN_CLICKED:
    					if((HWND)lParam==hButtonTalk){
    						TalkPressed(hwnd);
    					}
    					break;
    				case MENU_FILE_EXIT:
    					CloseProgram(hwnd);
    					break;
    				case MENU_HELP_VERSION:
    					DisplayVersion();
    					break;
    				case MENU_HELP_HELP:
    				case MENU_HELP_ABOUT:
    					break;
    			}
    			break;
    		case WM_DESTROY:
    			PostQuitMessage(0);
    		break;
    		default:
    			return DefWindowProc(hwnd, msg, wParam, lParam);
    	}
    	return 0;
    }
    
    void static CreateControls(HWND hwnd){
    	HFONT hFont = CreateFont(FONT_HEIGHT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FONT_NAME);
    
    	hEditLog = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "EDIT", "",
    							WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_LEFT | ES_READONLY | ES_WANTRETURN,
    							0, 0, WND_WIDTH-10, WND_HEIGHT-100, hwnd, NULL, ghInstance, NULL);
    
    	hEditInput = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
    								WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_LEFT,
    								0, WND_HEIGHT-90, WND_WIDTH-50, 25, hwnd, NULL, ghInstance, NULL);
    
    	hButtonTalk = CreateWindowEx(WS_EX_CONTROLPARENT, "BUTTON", "Talk",
    								WS_BORDER | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    								WND_WIDTH-30, WND_HEIGHT-90, 50, 25, hwnd, NULL, ghInstance, NULL);
    
    	if(hEditLog==NULL||hEditInput==NULL||hFont==NULL){
    		ERRBOX(ERR_TITLE, ERR_CHILD_WND);
    		CloseProgram(hwnd);
    	}
    
    	SendMessage(hEditLog, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
    	SendMessage(hEditInput, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
    }
    
    void static CreateMenus(HWND hwnd){
    	HMENU hMenu;
    	HMENU hSubMenu;
    
    	hMenu = CreateMenu();
    
    	hSubMenu = CreatePopupMenu();
    	AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&File");
    	AppendMenu(hSubMenu, MF_STRING, MENU_FILE_EXIT, "E&xit");
    
    	hSubMenu = CreatePopupMenu();
    	AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Help");
    	AppendMenu(hSubMenu, MF_STRING, MENU_HELP_HELP, "&Contents");
    	AppendMenu(hSubMenu, MF_SEPARATOR, 0, NULL);
    	AppendMenu(hSubMenu, MF_STRING, MENU_HELP_VERSION, "&Version");
    	AppendMenu(hSubMenu, MF_STRING, MENU_HELP_ABOUT, "&About");
    
    	SetMenu(hwnd, hMenu);
    }
    
    void static DisplayVersion(void){
    	char Buffer[1024];
    	sprintf(Buffer, "%s\nCompiled on %s at %s",MSG_VERSION, __DATE__, __TIME__);
    	MSGBOX("Information", Buffer);
    }
    
    void static ResizeWindow(HWND hwnd){
    	RECT Wnd;
    	RECT EditLog;
    	RECT EditInput;
    	RECT Button;
    	int WndHeight = 0;
    	int WndLegnth = 0;
    	int ButtonLegnth = 0;
    	int ButtonHeight = 0;
    
    	GetWindowRect(hwnd, &Wnd);
    	GetWindowRect(hEditLog, &EditLog);
    	GetWindowRect(hEditInput, &EditInput);
    	GetWindowRect(hButtonTalk, &Button);
    
    	WndHeight = Wnd.bottom-Wnd.top;
    	WndLegnth = Wnd.right-Wnd.left;
    	ButtonHeight = Button.bottom-Button.top;
    	ButtonLegnth = Button.right-Button.left;
    
    	SetWindowPos(hEditLog, NULL, 0, 0, WndLegnth-10, WndHeight-85, SWP_NOZORDER);
    	SetWindowPos(hEditInput, NULL, 0, WndHeight-80, WndLegnth-(ButtonLegnth+20), 25, SWP_NOZORDER);
    	SetWindowPos(hButtonTalk, NULL, (WndLegnth-ButtonLegnth-15), WndHeight-80, ButtonLegnth, 25, SWP_NOZORDER);
    }
    
    void static TalkPressed(HWND hwnd){
    	char Buffer[1024];
    
    	GetWindowText(hEditInput, Buffer, 1024);
    	sprintf(Buffer, "%s\r\n", Buffer);
    	SendMessage(hEditLog, EM_REPLACESEL, FALSE, (long int)Buffer);
    	SetWindowText(hEditInput, "");
    	SetFocus(hEditInput);
    }
    
    void CloseProgram(HWND hwnd){
    		DestroyWindow(hwnd);
    }
    Here are the two header files. I just lumped them together.
    Code:
    #include <windows.h>
    
    //	Macros
    #define MSGBOX(title,message)	MessageBox(hwndMain, message, title, MB_OK | MB_ICONINFORMATION)
    #define ERRBOX(title,message)	MessageBox(hwndMain, message, title, MB_OK)
    
    //	Basic Declarations
    #define TRUE	1
    #define FALSE	0
    
    #define SUCCESS	TRUE
    #define FAILURE FALSE
    
    //	Window Creation Information
    #define WND_TITLE	"Turing Test Window"
    #define WND_WIDTH	400
    #define WND_HEIGHT	200
    
    //	Edit Control Information
    #define FONT_HEIGHT	16
    #define FONT_NAME	"Arial"
    
    //	Memory Information
    #define DEBUG_MODE		TRUE
    #define MEM_LOG_FILE	"MemLog.txt"
    
    //	Chatting Information
    #define COMPUTER_NAME	"Esha"
    
    //	Messages/Error Messages
    #define ERR_TITLE		"Error"
    #define ERR_REG			"Could not register window class."
    #define ERR_WND			"Could not create window."
    #define ERR_CHILD_WND	"Child window could not be created."
    #define ERR_MEM			"Memory error."
    
    #define MSG_VERSION		"Turing Test Version 0.10"
    
    //	Global Prototypes
    //Main.c
    LRESULT CALLBACK WndMainProc(HWND,UINT,WPARAM,LPARAM);
    LRESULT CALLBACK WndEditSubProc(HWND,UINT,WPARAM,LPARAM);
    void CloseProgram(HWND);
    
    //MemMan.c
    HGLOBAL Free(HGLOBAL);
    HGLOBAL Memory(ULONG);
    void LogMemory(void);
    
    //	Global Structures
    
    
    //	Global Variables
    extern HINSTANCE ghInstance;
    extern HWND hwndMain;
    extern LPSTR gClassName;
    extern HWND hEditLog;
    extern HWND hEditInput;
    
    int static RegisterWindow(void);
    int static CreateMainWindow(int);
    void static CreateControls(HWND);
    void static CreateMenus(HWND);
    void static DisplayVersion(void);
    void static ResizeWindow(HWND);
    void static TalkPressed(HWND);
    
    #define MENU_FILE_EXIT	1500
    
    #define MENU_HELP_HELP	1600
    #define MENU_HELP_ABOUT	1601
    #define MENU_HELP_VERSION	1602
    - Sean
    Last edited by sean345; 07-06-2002 at 06:14 PM.
    If cities were built like software is built, the first woodpecker to come along would level civilization.
    Black Frog Studios

  9. #9
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Here's an example of catching than def button problem from an edit........

    Click Me ------->

  10. #10
    Registered User
    Join Date
    May 2002
    Posts
    317
    SendMessage(hButtonTalk, BM_CLICK, 0, 0);

    shouldn't this be BN_CLICKED?
    Last edited by Traveller; 07-06-2002 at 06:53 PM.

  11. #11
    the Corvetter
    Join Date
    Sep 2001
    Posts
    1,584
    Yeah, summed up (you guys pretty much answered it) just test during the entering of the edit control for the enter button and then take action, which would be the clicking of the button.
    1978 Silver Anniversary Corvette

  12. #12
    Registered User sean345's Avatar
    Join Date
    Mar 2002
    Posts
    346
    OK. Thanks for your guys' help.

    - Sean
    If cities were built like software is built, the first woodpecker to come along would level civilization.
    Black Frog Studios

  13. #13
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Code:
    case WM_COMMAND:
    switch(LOWORD(wParam))
    {
         case BN_CLICKED:
    should be more like
    Code:
    case WM_COMMAND:
    idControl = GET_WM_COMMAND_ID(wParam,lParam) ;
    switch(idControl)
    {
        case ID_BUTTON:
        if (BN_CLICKED == HIWORD(wParam))
    as you need to look for the HIWORD (not the LOWORD) to get the BN_CLICKED msg (and not the ctrl ID)

    Traveller
    SendMessage() with a BM_CLICK (button message 'click') actually ends up as a BN_CLICKED (button notification msg 'clicked') in the callback.
    Last edited by novacain; 07-07-2002 at 09:40 PM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  14. #14
    Registered User
    Join Date
    May 2002
    Posts
    317
    I see, thanx.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. BN_CLICKED, change button style
    By bennyandthejets in forum Windows Programming
    Replies: 13
    Last Post: 07-05-2010, 11:42 PM
  2. WM_CAPTION causing CreateWindowEx() to fail.
    By Necrofear in forum Windows Programming
    Replies: 8
    Last Post: 04-06-2007, 08:23 AM
  3. 6 measly errors
    By beene in forum Game Programming
    Replies: 11
    Last Post: 11-14-2006, 11:06 AM
  4. OpenGL Window
    By Morgul in forum Game Programming
    Replies: 1
    Last Post: 05-15-2005, 12:34 PM
  5. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM