I was wondering how to move between text boxes without using the mouse. Likewise, I would like to be able to trap function keys (F1-F12, Ctrl and Alt keys, etc.). It occurred to me that there might be another way other than text boxes to get multiple pieces of user data (name, address, etc.) that would accept the tab key to move from field to field? Here is my code:
I know there is a way to insert code with a schroll bar, but I haven't figured out how to do it. I tried attaching it, but I am not sure it worked. Here's the code:
#include <windows.h>
#include <stdio.h>
#define ID_MYBUTTON 101
#define ID_TAB 201
LPSTR szClassName = "MyClass";
HINSTANCE hInstance;
LRESULT CALLBACK MyWndProc(HWND, UINT, WPARAM, LPARAM);
HWND hwndText[3];
FILE *fp;
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
WNDCLASS wnd;
MSG msg;
HWND hwnd;
HWND hWndBtn1;
hInstance = hInst;
wnd.style = CS_HREDRAW | CS_VREDRAW; //we will explain this later
wnd.lpfnWndProc = MyWndProc;
wnd.cbClsExtra = 0;
wnd.cbWndExtra = 0;
wnd.hInstance = hInstance;
wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION); //default icon
wnd.hCursor = LoadCursor(NULL, IDC_ARROW); //default arrow mouse cursor
wnd.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wnd.lpszMenuName = NULL; //no menu
wnd.lpszClassName = szClassName;
if(!RegisterClass(&wnd)) //register the WNDCLASS
{
MessageBox(NULL, "This Program Requires Windows NT",
"Error", MB_OK);
return 0;
}
hwnd = CreateWindow(szClassName,
"Window Title",
WS_OVERLAPPEDWINDOW, //basic window style
CW_USEDEFAULT,
CW_USEDEFAULT, //set starting point to default value
CW_USEDEFAULT,
CW_USEDEFAULT, //set all the dimensions to default value
NULL, //no parent window
NULL, //no menu
hInstance,
NULL); //no parameters to pass
// create a text box and store the handle
hwndText[0] = CreateWindow(
TEXT("edit"), // The class name required is edit
TEXT("Enter text here"), // Default text.
WS_VISIBLE | WS_CHILD | WS_BORDER, // the styles
100,100, // the left and top co-ordinates
300,30, // width and height
hwnd, // parent window handle
(HMENU) ID_TAB, // the ID of your combobox
hInstance, // the instance of your application
NULL
); // extra bits you dont really need
hwndText[1] = CreateWindow(
TEXT("edit"), // The class name required is edit
TEXT("2nd field"), // Default text.
WS_VISIBLE | WS_CHILD | WS_BORDER , // the styles
100,200, // the left and top co-ordinates
300,30, // width and height
hwnd, // parent window handle
NULL, // the ID of your combobox
hInstance, // the instance of your application
NULL
); // extra bits you dont really need
SetWindowText(hwndText[0],"revised");
SetFocus(hwndText[0]);
CreateWindow(TEXT("STATIC"), TEXT("Text1:"), WS_CHILD|WS_VISIBLE, 25, 100, 55, 22, hwnd, 0, hInstance, 0);
hWndBtn1 = CreateWindow(TEXT("BUTTON"), TEXT("Update"), WS_CHILD|WS_VISIBLE, 5, 5, 55, 22, hwnd, (HMENU) ID_MYBUTTON, hInstance, 0);
ShowWindow(hwnd, iCmdShow); //display the window on the screen
UpdateWindow(hwnd); //make sure the window is updated correctly
while(GetMessage(&msg, NULL, 0, 0)) //message loop
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
char data[256];
switch(msg)
{
case WM_KEYDOWN:
if (wParam==27) SetFocus(hwndText[1]);
break;
case WM_COMMAND:
if(ID_MYBUTTON == LOWORD(wParam))
{
if (BN_CLICKED==HIWORD(wParam)) {
GetWindowText(hwndText[0],data,255);
MessageBox(hwnd,data,"notice",MB_OK);
if ((fp=fopen("tom","w"))==NULL)
MessageBox(hwnd,"could not open wikiwin.txt","error",MB_OK);
fprintf(fp,"%s\n",data);
fclose(fp);
}
}
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
That's done with your message dispatcher loop...
while(GetMessage(&msg, NULL, 0, 0)) //message loop
if (! TranslateAccellerator(hWnd,hAccelTable,&msg)) // process keyboard
if(! IsDialogMessage(hWnd,&msg)) // handle tabbing
{ TranslateMessage(&msg);
DispatchMessage(&msg); }
Also... to make debugging a lot easier, I never put code in my WinProc's switch() statements. I write a separate function for each window message I handle and call them from the switch(). It may seem like more work but it makes debugging a whole lot easier ... especially when it's the switch() itself that's gone awry.
Thanks. That worked. Once I process the keyboard, how do I distinguish function keys (F1, F2, Alt-a, etc.). In C I did this by using _getch() and translating the ascii code. Also, how do I specify a password field?
Quote from: tpekar on June 23, 2011, 05:04:25 PM
Also, how do I specify a password field?
Add an edit control with the password style.
You may wish to take a look at the control definitions at MSDN - Windows Controls (http://msdn.microsoft.com/en-us/library/bb773173%28VS.85%29.aspx)
Quote from: tpekar on June 23, 2011, 05:04:25 PM
Thanks. That worked. Once I process the keyboard, how do I distinguish function keys (F1, F2, Alt-a, etc.). In C I did this by using _getch() and translating the ascii code. Also, how do I specify a password field?
You would do that with the TranslateAccelerator function by building an accelerator table into your program's resources ... In POIDE click Help->Contents->Integrated Environment->POIDE Integrated Environment... read the resources section.
You would then use LoadAccelerator() after making the main window but before the message dispatcher starts, and use it's handle in the TranslateAccelerator() function...
Basically Accelerator tables translate a keypress into a WM_COMMAND message... If, for example you have a "Refresh" button producing a WM_COMMAND value of 100, you can also assign a keystroke to that button by having F7 produce the 100 value as well. Keyboard accelerators can be any key on the board. They can match buttons on your UI or they can have their own values... the only requirement is that you have code in your program that can deal with the values they generate.
Creating Accel-table dynamically:
HACCEL InitAccel(void)
{
ACCEL ac[2];
ac[0].key = VK_F1;
ac[0].fVirt = FVIRTKEY;
ac[0].cmd = IDM_TEST1;
ac[1].key = VK_F2;
ac[1].fVirt = FVIRTKEY;
ac[1].cmd = IDM_TEST2;
return CreateAcceleratorTable(ac, 2);
}
In WinMain():
HACCEL hAccel = InitAccel();
while (GetMessage(&msg, NULL, 0, 0)) //message loop
{
if (! TranslateAccelerator(hwnd,hAccel,&msg))
if (!IsDialogMessage(hwnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;