|
This is my first form in c++ win32, and I want to get the tab key rolling for testing my program code, so when I fill in the edit boxes, I can just tab to the text box.
I put this form in a mdi child window, and all the samples I found use a dialog box. GetDialogItem was quite popular.
With the create window, I added the WS_TABSTOP.
If I can figure out the message generated by having focus in the textbox, and pressing the tab key, I think I can get the message in the wndProc, and set the focus to the next textbox.
txt_Manage_CreateAccount_LastName_Field = CreateWindow(TEXT("edit"),
TEXT(""),
WS_TABSTOP | WS_CHILD | WS_VISIBLE | WS_BORDER | SS_LEFT,
winWidth - 205,
92,
180, 20,
hManage_CreateAccount,
(HMENU) IDC_MANAGE_CREATEACCOUNT_LASTNAME,
GetModuleHandle(NULL),
NULL
);
SendMessage(txt_Manage_CreateAccount_LastName_Field, WM_SETFONT, (WPARAM)hFont_txt, FALSE);
ShowWindow(txt_Manage_CreateAccount_LastName_Field, SW_SHOW);
|
|
|
|
|
jkirkerx wrote: ...so when I fill in the edit boxes, I can just tab to the text box.
What are you saying here? I consider edit boxes and text boxes to be one in the same.
jkirkerx wrote: If I can figure out the message generated by having focus in the textbox...
WM_SETFOCUS is sent to a window after it has gained the keyboard focus.
jkirkerx wrote: ...and set the focus to the next textbox.
Have you looked at GetNextDlgTabItem() ?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
DavidCrow wrote: What are you saying here? I consider edit boxes and text boxes to be one in the same.
I call them textboxes, was not sure of the exact nomenclature used by Pro's
DavidCrow wrote: Have you looked at GetNextDlgTabItem() ?
I did, but read too much into it indicating it would not work on a regular window, because the tab message would never be sent. It had to be a dialog box sending the message. I sort of tried it, but it was hard to test in the wndProc. If I put a F9 in the loop, I could not set the focus in the textbox and press tab key, because the loop kept stopping at the breakpoint.
Let me try it again.
|
|
|
|
|
I had to move a lot of dirt to get the lowdown on that advice, but overall in the end, it will work soon today
I Added the DS_CONTROL, and the WS_EX_CONTROL_PARENT, which is suppose to extend dialog messaging to my MDI Child Window, and added a method to see the message from the tab key, and a intercept.
I loaded this in my form load function. Can't get a handle back from GetNextTabItem, so I will go back and check my window settings.
I'm not sure if what I wrote is sane or not, but it's a start.
BOOL bReturn = FALSE;
while (GetMessage(&msg, NULL, 0, 0)) {
if (bReturn == -1) {
}
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
WCHAR szMessage[50];
wsprintf(szMessage, L"msg=%u wparam=%u lparam=%u", msg.message, msg.wParam, msg.lParam);
SetWindowText(lbl_Manage_CreateAccount_Status, szMessage);
if (msg.message == WM_CHAR) {
if ( msg.wParam == 9) {
if ( msg.lParam == 983041 ) {
HWND nextTab;
nextTab = GetNextDlgTabItem(gManage, lbl_Manage_Label, FALSE);
DWORD errorCode = GetLastError();
SetFocus(nextTab);
}
}
}
}
}
|
|
|
|
|
|
I read the blog, good information, I just need to let it soak in for awhile.
I thinking that I need to abandon the whole gui part of my program and start again. Maybe I really blew it and should of used Dialog boxes for all my forms. Coming from Visual Basic, in that world, there pretty much all called forms, and you can assign a value to them to change the type they are.
I put this in my form load function of my MDI child Window, but I need to figure out what the message is when I press the tab key, and where to listen for that specific message so I can issue the go to next textbox. It's suppose to be some sort of message pre-processor, that will fork out the message to 2 different types of listeners.
BOOL bReturn = FALSE;
while (GetMessage(&msg, NULL, 0, 0)) {
if (bReturn == -1) {
}
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
ReleaseDC(NULL, hdc);
|
|
|
|
|
Forget all this manually handling keys like you're doing below. Even if you succeeded you'll have all this messy code that's already built into the OS. Also, there's more to the dialog keyboard interface than tab, like the arrow keys. The answer is the IsDialogMessage function. Change you message pump so it looks something like this:
MSG m;
while(GetMessage(&m, NULL, 0, 0))
{
if (!IsDialogMessage(hManage_CreateAccount, &m))
{
TranslateMessage(&m);
DispatchMessage(&m);
}
}
Steve
|
|
|
|
|
I built on it even more today, and made it bigger, and thought I optimized it a bit more.
My thinking is saying only translate and dispatch DialogMessages?, and then run the rest of my code as is. Or wrap my new code in the if statement.
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
switch (msg.message) {
case WM_LBUTTONDOWN:
{
WCHAR *szTempData[150];
int iLength = SendMessageW(GetFocus(), WM_GETTEXT, (WPARAM)150, (LPARAM)szTempData );
if ( iLength > 0 ) {
SendMessage(GetFocus(), EM_SETSEL, 0, -1);
}
}
break;
case WM_CHAR:
short ks = GetKeyState(VK_SHIFT);
if (msg.wParam == VK_TAB) {
if (ks >= 0) {
SetFocus(GetNextDlgTabItem(hManage_CreateAccount, GetFocus(), FALSE));
}
else {
SetFocus(GetNextDlgTabItem(hManage_CreateAccount, GetFocus(), TRUE));
}
WCHAR *szTempData[150];
int iLength = SendMessageW(GetFocus(), WM_GETTEXT, (WPARAM)150, (LPARAM)szTempData );
if ( iLength > 0 )
SendMessage(GetFocus(), EM_SETSEL, 0, -1);
}
break;
}
}
|
|
|
|
|
Dump all the code above and replace it with mine.
Steve
|
|
|
|
|
So I spent a whole day writing all that for nothing?
Why does all the functionality that I wrote still works?
|
|
|
|
|
Firstly, have you tried the code I posted and does it work for you?
"Nothing" is a bit strong, you no doubt learnt something.
As to why it works, that's better explained in the original link I posted, in short it's because that's what the function is for.
Steve
|
|
|
|
|
All the functionality that I wrote works with 4 lines of your code.
Just upset because time is finite, and yes I did learn something, but at what price?.
Don't take it personally if I don't sound grateful. Give me a day to cool off.
I was so proud of myself for figuring it out, only to find out that I could of just bent time and space instead of traveling a great distance across the universe.
|
|
|
|
|
No offense taken. Every programer as had that experience.
Steve
|
|
|
|
|
Yeah it works now, but I want to backwards to.
How to detect shift + tab, or pull it out of the message
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
if (msg.message == WM_CHAR) {
if (msg.wParam == VK_TAB) {
SetFocus(GetNextDlgTabItem(hManage_CreateAccount, GetFocus(), FALSE));
}
else if ((msg.wParam == VK_TAB) && (msg.lParam == VK_SHIFT)) {
SetFocus(GetNextDlgTabItem(hManage_CreateAccount, GetFocus(), TRUE));
}
}
}
|
|
|
|
|
Obviously wParam can't be both VK_TAB and VK_SHIFT at the same time, so you'll have to check if shift is being held down when tab is pressed. Try using GetKeyState()[^]
|
|
|
|
|
I just figured that out, maybe I can detect the ks in a better way, something about the high and low order. but it goes forward and backwards now, and in my MDI Child window. So I don't have to dump my GUI's and convert them to dialogs.
Lesson hard learned after reading all those articles and tips.
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
if (msg.message == WM_CHAR) {
short ks = GetKeyState(VK_SHIFT);
if (msg.wParam == VK_TAB) {
if (ks >= 0) {
SetFocus(GetNextDlgTabItem(hManage_CreateAccount, GetFocus(), FALSE));
}
else {
SetFocus(GetNextDlgTabItem(hManage_CreateAccount, GetFocus(), TRUE));
}
}
}
}
|
|
|
|
|
I know how to do this in C++, but a bit rusty on C,
char line[1024]="d(Text1)b(ID1)n(node1)d(Text2)b(ID2)n(node2)d(Text3)b(ID3)n(node3)...
I would like to parse the line above into item0 = d(Text1)b(ID1)n(node1), item2 - d(Text2)b(ID2)n(node2)... and so forth
char *py;
char *px = line;
while ((py=strstr(px,"d(")) != NULL) {
px++;
}
return 0;
Thanks
|
|
|
|
|
|
so, is it "n(nodename)" that signals the end of a 'node' and "d(whatever)" for the start?
i always find state-machines the easiest way to do simple parsing.
off the top of my head...
typedef struct item_t
{
char d[100];
char b[100];
char n[100];
} item;
const char *consume_between_parens(const char *p, char *out)
{
if (*p!='(') return NULL;
p++;
while (*p)
{
if (p==')')
{
p++;
break;
}
*out = *p;
out++; p++;
}
return p;
}
void parse(const char *p, itemArray array ... some array thing)
{
enum {wantD, wantB, wantN} state = wantD;
item * curItem = null;
while (*p)
{
switch (state)
{
case wantD:
if (*p=='d')
{
curItem = malloc(sizeof(item));
p = consume_between_parens(p, curItem->d);
state = wantB;
}
else error
break;
case wantB:
if (*p=='b')
{
p = consume_between_parens(p, curItem->b);
state = wantN;
}
else error
case wantN:
if (*p=='n')
{
p = consume_between_parens(p, curItem->n);
addToArray(array, curItem);
state = wantD;
}
else error
break;
default:
error;
}
p++;
}
while
|
|
|
|
|
Fantastic! I did get it to work with very minor modifications.
typedef struct item_t
{
char d[8192];
char n[8192];
char i[8192];
} item;
char *consume_between_parens(char *p, char *out)
{
p++;
if (*p!='(') return NULL;
int paren_count = 1;
p++;
while (*p)
{
if (*p=='(')
paren_count++;
if (*p==')')
paren_count--;
if(!paren_count) break;
*out = *p; out++; p++; }
return p;
}
void parse(char *p)
{
item * curItem = NULL;
while (*p)
{
if (*p=='d')
{
curItem = (item*)malloc(sizeof(item));
p = consume_between_parens(p, curItem->d);
}
if (*p=='n')
{
p = consume_between_parens(p, curItem->n);
}
if (*p=='i')
{
p = consume_between_parens(p, curItem->i);
}
p++;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char *text ="1:7\22\\d(2011)n(0)i(711910)d(2010)n(1)i(711911)";
parse(text);
return 0;
}
|
|
|
|
|
Have you looked at strtok() ?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
I just did. Thanks for mentioning it, this function actually makes things a lot easier, since it does most of the pointer work for you. I will give it a try.
Thanks again
|
|
|
|
|
I have one more question C- related:
char *getLine(char *p, char *out)
{
int Dees = 0;
char *px = p;
p++;
if (*p!='(') return NULL;
int paren_count = 1;
while (*px)
{
if(*px=='d')
{
Dees++;
if(Dees >1 && *(px+1)=='(') break;
}
*out = *px; out++; px++; }
return px;
}
char *px="d(text)n(0)l(1)d(text2)n(1)l(2)...";
char line[8192];
char *py = getLine(px,line);
In the main program, after calling the function getLine(), I do get line correctly as in "d(text)n(0)l(1)" but filled with garbage after that as its trying to fill out 8192 characters. How do I make it not fill the rest of the unused space. Note, I don't know the size of "line" as it varies, but I need it big enough. I know strcpy could be useful here somewhere, just can't get it to work.
I also tried in getLine() the following:
char field[4095];
strcpy(field,out);
But nothing gets copied, out shows null in the debugger.
Thanks
modified 12-Dec-11 12:00pm.
|
|
|
|
|
After the while() loop, you need to terminate out with a '\0' character.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
modified 12-Dec-11 14:26pm.
|
|
|
|
|
Fabulous!
while (*px != '\0') did the trick. I have to admit i don't quite get it though, In the string "d(2011)n(0)i(711910)d(2010)n(1)i(711911)", I am telling to break out when it sees the next 'd(', so why do I need the terminating character? Could you clarify?
Thanks much
|
|
|
|
|