Thread: Simple WinAPI code problem.

  1. #1
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34

    Question Simple WinAPI code problem.

    Well I'm new in WinAPI, and can't figure why this does not work.
    All I want to do is write a number in the edit box, and press a button to make the number appear in a CTEXT just below it. (and if possible save the number into a variable).
    Code:
    BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {
    switch(Message)
        {
        case WM_INITDIALOG:
        break;
        case WM_COMMAND:
        switch(LOWORD(wParam))
        {
               case IDC_MYBUTTON:
                    BOOL Funciono;
                    int var = GetDlgItemInt(hwnd, IDC_NUMBER, &Funciono, FALSE); //IDC_NUMBER is an EDIT box.
                    if( Funciono == TRUE )
                        {
                                 SetDlgItemInt(hwnd, IDC_SHOWVAR, var, "-");//IDC_SHOWVAR is a CTEXT.
                        }
                    break;   
               case IDCANCEL:
                    EndDialog(hwnd, IDCANCEL);
                    break;
        }
        break;
        default: return FALSE;
        }
    return TRUE;
    }
    Then there is the rest of the window code which has no problems.

    The error jumps in the "BOOL" part, thanks for any help.

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    "Does not work".
    Mainframe assembler programmer by trade. C coder when I can.

  3. #3
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34
    Quote Originally Posted by Dino View Post
    "Does not work".
    .... ?

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Pecado View Post
    Well I'm new in WinAPI, and can't figure why this does not work.
    All I want to do is write a number in the edit box, and press a button to make the number appear in a CTEXT just below it. (and if possible save the number into a variable).

    Then there is the rest of the window code which has no problems.
    The error jumps in the "BOOL" part, thanks for any help.
    Ok, first thing... if you want windows code that doesn't constantly mess up, you really should not put code in switch statements... you should write a function and call it from the switch statement.

    Second, boolean flags in windows are TRUE and FALSE, not "+" and "-"....

    Code:
    VOID MoveVar(void)
      { BOOL MGood = false;
         INT Value = 0;
         int value = GetDlgItemInt(hwnd, IDC_NUMBER, &MGood, TRUE);box.
         if(MGood )
           SetDlgItemInt(hwnd, IDC_SHOWVAR, Value, TRUE); }
    
    
    switch LOWORD(wParam)
       { ...
    
          case IDC_MYBUTTON :
              MoveVar();
               break;
         ....
                    }

  5. #5
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34
    Thanks a lot for the advice, yes it may be better to call functions from the cases rather than writing them there.

    I understand the code you wrote for me (thanks by the way), and after reforming everything to fit it in... it tells me that "hwnd" is undeclared... I tried sticking it inside wndproc and dlgproc where HWND seems to be declared, but still... any idea what may be the reason?

    EDIT: just had to declare it, sorry just getting used to this. However, the code is not working... and I've no idea why, I've put a message box in the end so I make sure it is actually happening, but still it isn't... :S. thanks for the help anyways.

    EDIT2: Apparently, MGood isn't returing a TRUE value so the if statement isn't happening...
    Last edited by Pecado; 12-03-2010 at 03:41 PM.

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Pecado View Post
    Thanks a lot for the advice, yes it may be better to call functions from the cases rather than writing them there.
    The one thing C does not let you do is nest functions. It may not be faster or easier to declare a function for every window message you hancle, but it is far more sane and stable.

    EDIT: just had to declare it, sorry just getting used to this. However, the code is not working... and I've no idea why, I've put a message box in the end so I make sure it is actually happening, but still it isn't... :S. thanks for the help anyways.
    EDIT2: Apparently, MGood isn't returing a TRUE value so the if statement isn't happening...
    You know what... some windows functions are so not prone to failure you can ignore the error traps... Post your code, lets see where we're at...
    Last edited by CommonTater; 12-03-2010 at 11:36 PM.

  7. #7
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34
    Sure, thanks for the help man... I don't know how else to search for this problem on the internet... no solution.
    Here it goes:
    Code:
    HWND hwnd; //I've done this because if not it'd say hwnd is not declared.
    VOID MoveVar(void)
        {
         BOOL MGood = FALSE;
         int var = 0;
         var = GetDlgItemInt(hwnd, IDC_NUMBER, &MGood, TRUE);
             if(MGood == TRUE)
             {SetDlgItemInt(hwnd, IDC_SHOWVAR, var, TRUE);
               MessageBox(hwnd, "This msgbox doesn't popup...", "...", MB_OK);
             }
        MessageBox(hwnd, "This msgbox does popup...", "...", MB_OK);
        }
           
    BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {
    switch(Message)
        {
        case WM_INITDIALOG:
        break;
        case WM_COMMAND:
        switch(LOWORD(wParam))
        {
               case IDOK:
                    EndDialog(hwnd, IDOK);
                    break;
               case IDC_METAL:
                    MoveVar(); //due to the 2nd msgbox I know the button is working.
                    break;
               case IDC_NUMBER:
                    break;                
               case IDCANCEL:
                    EndDialog(hwnd, IDCANCEL);
                    break;
        }
        break;
        default:
        return FALSE;
        }
    return TRUE;
    }

  8. #8
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Ahhh... now I see where your problem is...

    Try it like this...

    Code:
    // declare hwnd in the function's parameters
    
    VOID MoveVar(HWND hwnd)
        {
          int var = 0;
         var = GetDlgItemInt(hwnd, IDC_NUMBER, NULL, TRUE);
         SetDlgItemInt(hwnd, IDC_SHOWVAR, var, TRUE);
    
    MessageBox(hwnd, "Opcion 3", "...", MB_OK);
    
       }
     
    
    // in your switch pass hwnd into the function
    
    MoveVar(hwnd);
    The thing is that the two calls involved practically never fail, so you can cheat just a little as I've shown you. The message box won't show you anything the second control won't...

    FWIW... adding a Beep(500,200); where you have the message box will make it sound off and keep on trucking so you can see if it's working correctly without having to click on stuff all the time.
    Last edited by CommonTater; 12-03-2010 at 05:09 PM.

  9. #9
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34
    1º You read the first post which was accidentally posted(sorry), but was basically the same.

    2º IT WORKS, you're a real life saver!! All I needed to do is add the hwnd declaration in the MoveVar and then redirect it the way you told me. I'd have never found out. Thanks really man!! Now I can go on, I was really stuck with this... Well, hope to see you around in my likely to be next doubt xD.
    Last edited by Pecado; 12-03-2010 at 05:15 PM.

  10. #10
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Pecado View Post
    1º You read the first post which was accidentally posted(sorry), but was basically the same.

    2º IT WORKS, you're a real life saver!! All I needed to do is add the hwnd declaration in the MoveVar and then redirect it the way you told me. I'd have never found out. Thanks really man!! Now I can go on, I was really stuck with this... Well, hope to see you around in my likely to be next doubt xD.
    No worries... I was glad to help.

  11. #11
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    I would add the ES_NUMBER style to the IDC_NUMBER edit to restrict input to only digits.

    [picky]
    Do you set a default value in the IDC_NUBER edit? (and is zero valid input?)

    If the user has not entered a number, the code will set the IDC_SHOWVAR edit to '0' (as GetDlgItemInt() returns zero on error/no input)

    You can use the Edit_GetTextLength macro as a filter for lack of input.

    Code:
    //check that the user has entered a number in the edit
    if(Edit_GetTextLength(GetDlgItem(hwnd,IDC_NUMBER)))//empty edit returns zero
    {
        //process input
    }
    else
    {
        //ask user for input
    }
    EDIT:
    <<edited out incorrect info in case someone uses it....>>

    Your code always returns TRUE for messages you process. This is not 100% correct code.
    Some messages require differing returns to show you have processed the message (ie WM_CTLCOLORDLG wants a HBRUSH as a return. If the OS casts your return of TRUE as a HBRUSH 'bad things' may happen...)
    Last edited by novacain; 12-04-2010 at 12:18 AM.
    "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

  12. #12
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by novacain View Post
    You can use the Edit_GetTextLength macro as a filter for lack of input.
    Since this is in a dialogue and he is using GetDlgItemInt(), if he really needs to check he can just check the return value for 0.


    Your code returns FALSE for messages you do not process (have code for). You should/must call DefWindowProc() to allow the OS to perform any default processing.
    You don't call DefWindowProc() from a dialogue box message loop.


    Using Dialog Boxes (Windows)
    Last edited by CommonTater; 12-03-2010 at 11:34 PM.

  13. #13
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by CommonTater View Post
    Since this is in a dialogue and he is using GetDlgItemInt(), if he really needs to check he can just check the return value for 0.
    What if the user enters a '0' and you filter it out as 'bad' input?

    You can not check the return of an GetDlgItemInt() for errors if you do not use the lpTranslated flag (set it to NULL).

    As I said, I was being picky. It all depends on what will happen if 'bad' data is processed.

    Quote Originally Posted by CommonTater View Post
    You don't call DefWindowProc() from a dialogue box message loop.
    Opps...my bad. For some reason it did not register that it was a dialog.
    Last edited by novacain; 12-04-2010 at 12:16 AM.
    "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
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by novacain View Post
    What if the user enters a '0' and you filter it out as 'bad' input?

    You can not check the return of an GetDlgItemInt() for errors if you do not use the lpTranslated flag (set it to NULL).

    As I said, I was being picky. It all depends on what will happen if 'bad' data is processed.
    The lpTranslated flag doesn't catch bad data... it gives an indication whether the function call suceeded or not. Causes of failure would be things like an invalid window handle, an invalid dialog item number, etc. but not the content of the edit box. If you type "hello" then call GetDlgItemInt() it simply returns 0...

    The thing is these functions, along with a host of others, almost never fail so error trapping every one of them becomes pretty much a waste of code.

    I will insist that error trapping is a good thing... but it's not always a necessary thing.

  15. #15
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34
    Since the thread was continued, I'll throw a question:

    I have a main dialog(dlg1), and a dialog that pops up after pressing a button in the main one (dlg2).
    dlg2 has the DS_CONTROL in the resource.
    But whenever I press cancel in dlg2, it closes both dlg1 and dlg2, and I want to close only dlg2.
    I tried to define a different hwnd but it doesn't seem to work. Any ideas?

    By the way, in IDCANCEL I use "EndDialog(hwnd, IDCANCEL);".

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  2. Problem using java programs within C code
    By lemania in forum Linux Programming
    Replies: 1
    Last Post: 05-08-2005, 02:02 AM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  4. Simple Code, looking for input.
    By Alien_Freak in forum C Programming
    Replies: 3
    Last Post: 03-03-2002, 11:34 AM
  5. Simple Compile Time Problem - HELP!
    By kamikazeecows in forum Windows Programming
    Replies: 2
    Last Post: 12-02-2001, 01:30 PM