Thread: Simple WinAPI code problem.

  1. #31
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34
    @morongo, thanks man but I wasn't talking about an editbox, but of a listbox/combobx. thanks anyways.

    @Tater yes, I know I still put them inside, it's just that I come from C/C++ programming where I used to place even hundreds of code lines inside a case... I even got to various switchs inside each other... so well it's a matter of forgetting the habit :S.

    Anyways, about the code you show me, only the code concerning the fetch of list and show in static should be enough right?... but apparently it is reluctant to display the string.
    Firstly, I thought that:
    Code:
    SendDlgItemMessage(hwnd, IDC_COMBOBOX,CB_GETLBTEXT,idx,0);
    Should have the Buffer char like this:
    Code:
    SendDlgItemMessage(hwnd, IDC_COMBOBOX,CB_GETLBTEXT,Buffer,0);
    Or:
    Code:
    SendDlgItemMessage(hwnd, IDC_COMBOBOX,CB_GETLBTEXT,Buffer,256);
    But it still wouldn't work. (and it's not inside the case).
    So.. I've no idea what's going on. And also, what do you mean by "fetch 'display' to static"? What's what you call display? (thanks in advance once again.).

    EDIT: Sorry! I just had to employ the second piece of code :S Now it works perfectly, thanks once again!!!!!!!!!!!!!!
    Last edited by Pecado; 12-06-2010 at 05:42 PM.

  2. #32
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Pecado View Post
    @Tater yes, I know I still put them inside, it's just that I come from C/C++ programming where I used to place even hundreds of code lines inside a case... I even got to various switchs inside each other... so well it's a matter of forgetting the habit :S.
    It's not obligatory Windows programming... it's just a whole lote easier to debug and maintain... even in C or C++... Plus, as I pointed out it strongly localizes variables so you don't end up with redefinition and pointer type errors that defy troubleshooting. Thing is Windows makes very heavy use of switch statements, often nested several layers deep... it can be a nightmare to sort out a failed message loop... my way just makes it a whole lot easier.

    Anyways, about the code you show me, only the code concerning the fetch of list and show in static should be enough right?... but apparently it is reluctant to display the string.
    My apologies... it's been a looooong day and it's only supper time here...

    Code:
         idx = SendDlgItemMessage(hwnd, IDC_COMBOBOX,CB_GETCURSEL,0,0)
         SendDlgItemMessage(hwnd, IDC_COMBOBOX,CB_GETLBTEXT,idx,(LPARAM)buffer);
         SetDlgItemText(hwnd,IDC_STATIC7,Buffer);
    This, btw is why you should never try to cut and past code (especially mine)... I can point you in the right direction but I am not above making mistakes... In fact, I make lots of them.

    So.. I've no idea what's going on.
    You should snag this...

    Download details: Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1

    It's a hard disk resident copy of the Windows 7 Software Development Kit (SDK). It comes with samples, full documentation of all windows calls, even some handy debugging tools.... Catch me in my mistakes by looking up the proper use of the functions

    And also, what do you mean by "fetch 'display' to static"? What's what you call display? (thanks in advance once again.).
    A combobox has two sections... a list which can be pulldown or box style and a display area that can be either an editor or a static depending on style settings. So... if it's not the list, it must be....
    Last edited by CommonTater; 12-06-2010 at 06:08 PM.

  3. #33
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Missed the 3rd page, my bad.
    Last edited by novacain; 12-06-2010 at 09:10 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

  4. #34
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34
    Is there something like:

    Code:
    LoadBitmap(hwnd,IDB_MYBMP);
    in WinAPI to load a bitmap upon selecting a combobox item? Thanks.

  5. #35
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Pecado View Post
    Is there something like:

    Code:
    LoadBitmap(hwnd,IDB_MYBMP);
    in WinAPI to load a bitmap upon selecting a combobox item? Thanks.
    This should be possible. Take the CBN_SELENDOK message from the combobox, get the index of the choice, figure out which bitmap, load the bitmap from resources and display it in a static control.

    In the static control set the SS_BITMAP style then to display an image send it the STM_SETIMAGE message with the bitmap's handle in LPARAM.

    If the image is stored in the program resources, you can use the LoadImage() function to get a compatible handle.

    You should check these in the SDK before proceeding, the particulars are a bit weird.
    (Which is totally normal for Windows)
    Last edited by CommonTater; 12-08-2010 at 03:19 PM.

  6. #36
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34
    Uhh, it's going to take a while to take that all in, I was getting the IDs like this:

    Code:
    void obtcomboconces(HWND hwnd)
      {char buffer[256]; int id=0;
          id=GetDlgItemText(hwnd, IDC_COMBOBOX,buffer,255);
          SetDlgItemText(hwnd,IDC_STATIC7,buffer);
          SetDlgItemInt(hwnd,IDC_STATIC8,id,FALSE);
          Beep(700,100);
      switch(id){case .. case... case...}
    And in the cases I was putting the functions.
    Although I must say the IDs quite annoyed me as they were random numbers which depended on what was written in the combobox string.

    So now I've looked for what you mentioned, the CBN_SELENDOK, and apparently it is meant to get the IDs as you say. I'll start by changing the way of getting IDs and then I'll attempt bitmaps xD.
    Should you have nothing to do and feeling generous, would you be able to give me a hint on how to use CBN_SELENDOK? I've looked everywhere but I'm too new to understand really... this is what I've tried unsuccesfuly:

    Code:
    CBN_SELENDOK(hwnd,IDC_COMBOCONCES);
    Last edited by Pecado; 12-08-2010 at 05:41 PM.

  7. #37
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    GetGlgItemText() does not return the list index, it returns the length of the string.

    CBN_SELENDOK is a windows message... Combo Box Notification... It does not give you the list index. It will give you the ID of the control in the LOWORD of it's WPARAM. It's LPARAM is the combox's handle.

    Ok... real world example here...

    Code:
    // part of a windows message loop...
    
                  case 4092 :                                // control ID
                    switch (HIWORD(wParm))
                      { case CBN_SELENDOK :
                          FixPulldownEnable(Dlg,LOWORD(wParm));
                          return 0;
                        default :
                          return 0; }
    (I don't use the IDC_ thing, I just use the control ID numbers directly and I'm betting somebody's gonna give me some stick about it...But, it works )

    Here's the function it calls...

    Code:
    // check enable states
    VOID FixPulldownEnable(HWND Dlg,INT List)
      { INT cs;   // selected list item
        cs = SendDlgItemMessage(Dlg,List,CB_GETCURSEL,0,0);
        // clear data if no selection
        if (cs < 1)
          { CheckDlgButton(Dlg,List - 4,0);
            CheckDlgButton(Dlg,List - 3,0);
            CheckDlgButton(Dlg,List - 2,0);
            CheckDlgButton(Dlg,List - 1,0); 
            SetDlgItemText(Dlg,List + 1,NULL); }
        else
          CheckDlgButton(Dlg,List - 4,1); }
    I don't know how helpful that will be... but does show you how to get the curent list index...

    Basically after CBN_SELENDOK you want to jump into your function, grab the list index (the display is not yet updated) and then do what you need to do with the list index value.

    In your case you might actually want to store the handle for the bitmap in the list's LPARAM storage for each item and use the index to retrieve that so you can put it in your static control...

    Here's an example of using the LPARAMS of each list item...

    This loads a Virtual Key table into a list...
    Code:
        for (x = 0; x < VKTABLE_COUNT; x++)
          { item = SendDlgItemMessage(Dlg,List,CB_ADDSTRING,0,(LPARAM) VKTable[x].Name);
            SendDlgItemMessage(Dlg,List,CB_SETITEMDATA,item,VKTable[x].VKey); }
    This gets the LPARAM data out of the list when exporting the data to struct...
    Code:
    // get the vkey from a pulldown list
    BYTE GetPulldown(HWND Dlg, INT List)
      { INT cs; // current selection
        cs = SendDlgItemMessage(Dlg,List,CB_GETCURSEL,0,0); 
        return (BYTE) SendDlgItemMessage(Dlg,List,CB_GETITEMDATA,cs,0); }
    All the really good stuff happens in messages...


    This is where you gain a lot by downloading and reading the Windows API documentation. If you don't want to or can't download it you can read most of it online at:

    Windows Development (Windows)

    If you want to know about comboboxes search for "combobox control"... it's all there.

  8. #38
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34
    Well, once again thanks.

    Now that you said that the way I was "getting the IDs" was just a count of letters, it's true, and that is why I had two different strings giving me the same value.
    I've been trying to get CBN_SELENDOK to work with the info you gave me, and after a little struggling, it worked. Now I get perfect IDs (0,1,2,3...). I've figured that out with a SetDlgItemInt in a Static.
    Allthough I haven't understood neither the virtual table nor the bitmap setting, I'm planning to get down to it tomorrow (exams exams exams), but thanks a lot man, you really know how to explain this stuff.

  9. #39
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Pecado View Post
    Well, once again thanks.

    Now that you said that the way I was "getting the IDs" was just a count of letters, it's true, and that is why I had two different strings giving me the same value.
    I've been trying to get CBN_SELENDOK to work with the info you gave me, and after a little struggling, it worked. Now I get perfect IDs (0,1,2,3...). I've figured that out with a SetDlgItemInt in a Static.
    Allthough I haven't understood neither the virtual table nor the bitmap setting, I'm planning to get down to it tomorrow (exams exams exams), but thanks a lot man, you really know how to explain this stuff.
    The ID actually comes from the CBM_GETCURSEL message. CBN_SELENDOK merely signals that a user has made a choice from the list portion of a combobox.

    The virtual key table example merely showed you how to load and retrieve the LPARAM storage that parallels the text in a combobox (or listbox). For every string in a combobox there is also a DWORD value. What you want to do probably has literally nothing to do with virtual keys...

    The important thing is to have the resources to look up and use windows messages... that's where all the really good stuff happens.

    I don't understand the application of GetDlgItemInt with static displays... unless you're using them to display numbers???

    Really... If you're going to continue Windows coding you NEED the SDK... There's just now way to do one without the other.

  10. #40
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34
    Now that you mention that, I've downloaded all the SDK files, documents, compilers debuggers (about 1GB of stuff), and avoided to install .NET stuff.
    However I find it all rather confusing, I entered the "Windows SDK Documentation" and "Samples Reference" and there is a list mentioning every function or command in WinAPI... but none of the common ones like SetDlgItemInt etc, I mean I find it a lot easier to search the internet for sources forums explaining it.

    EDIT: Ah ah, search function -.- forget what I've said.
    Last edited by Pecado; 12-10-2010 at 04:39 PM.

  11. #41
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Pecado View Post
    Now that you mention that, I've downloaded all the SDK files, documents, compilers debuggers (about 1GB of stuff), and avoided to install .NET stuff.
    However I find it all rather confusing, I entered the "Windows SDK Documentation" and "Samples Reference" and there is a list mentioning every function or command in WinAPI... but none of the common ones like SetDlgItemInt etc, I mean I find it a lot easier to search the internet for sources forums explaining it.

    EDIT: Ah ah, search function -.- forget what I've said.
    In the GUI on the toolbar you will find an indexbutton , at the top of that index you can type in the name of any api call , subsystem or control and get full details. For example: Type in "combobox".... I find this to be far more useful than either the search of the table of contents.

    In the contents you will find a list of all controls and reference to how the work, as well as examples.

    The search function is primarily for keywords, I don't use it a lot because it tries to do too much and can be very confusing.

  12. #42
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34
    I see, no the problem is I just had to get used to it...
    Now there's a little problem here...

    I've found this in the SDK docs, but it doesn't seem to apply:

    Code:
    lResult=SendMessage(      // returns HANDLE in lResult     
              (HWND) hwnd,      // handle to destination control     
              (UINT) STM_SETIMAGE,      // message ID     
              (WPARAM) IMAGE_BITMAP,      // = (WPARAM) () wParam;    
              (LPARAM)IDB_IMAGE1      // = (LPARAM) (HANDLE) lParam; 
              );
    Firstly, it tells me to define lResult, which I don't know how to define (I've tried int lResult but no..). And secondly, I've noticed I don't have a place to put the control of the picture box. Any idea what's going wrong? Thanks.

  13. #43
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Pecado View Post
    I see, no the problem is I just had to get used to it...
    Now there's a little problem here...

    I've found this in the SDK docs, but it doesn't seem to apply:

    Code:
    lResult=SendMessage(      // returns HANDLE in lResult     
              (HWND) hwnd,      // handle to destination control     
              (UINT) STM_SETIMAGE,      // message ID     
              (WPARAM) IMAGE_BITMAP,      // = (WPARAM) () wParam;    
              (LPARAM)IDB_IMAGE1      // = (LPARAM) (HANDLE) lParam; 
              );
    Firstly, it tells me to define lResult, which I don't know how to define (I've tried int lResult but no..). And secondly, I've noticed I don't have a place to put the control of the picture box. Any idea what's going wrong? Thanks.
    Well, in a dialog you would substitute SendDlgItemMessage()... So your call might look like this...
    Code:
    // load Image from file and place in Dlg, Item
    
    BOOL SetStaticImg(HWND Dlg, INT Item, PCHAR ImageFile)
      { HANDLE img;   // image handle
         img = LoadImage(NULL,ImageFile,IMAGE_BITMAP,0,0,LR_DEFAULTSIZE);
         if (!img)
          return FALSE;
        SendDlgItemMessage(Dlg,Item,SCM_SETIMAGE,IMAGE_BITMAP,(LPARAM)img);
        return TRUE; }
    You may have to do a bit more work... but that should give you the idea.


    For a more specific answer you need to tell me exactly what you're doing here... Are you loading a bitmap from resources? Are you getting it from a file? etc...
    Last edited by CommonTater; 12-10-2010 at 07:03 PM.

  14. #44
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by CommonTater View Post
    Well, in a dialog you would substitute SendDlgItemMessage()...
    Or use

    Code:
    SendMessage(GetDlgItem(hWnd, IDC_CONTROL), STM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM)IDB_IMAGE1 );
    Quote Originally Posted by CommonTater View Post
    So your call might look like this...

    Code:
    // load Image from file and place in Dlg, Item
    
    BOOL SetStaticImg(HWND Dlg, INT Item, PCHAR ImageFile)
      { HANDLE img;   // image handle
         img = LoadImage(NULL,ImageFile,IMAGE_BITMAP,0,0,LR_DEFAULTSIZE);
         if (!img)
          return FALSE;
        SendDlgItemMessage(Dlg,Item,SCM_SETIMAGE,IMAGE_BITMAP,(LPARAM)img);
        return TRUE; }
    This will leak GDI memory, as you do not call DeleteObject() on the previous bitmaps.

    It might work on a .NET version MSVC (which creates GDI objects as temp by default, but it is IMO very poor practice).

    Code:
    HBITAMP hReturn=NULL;
    hReturn = (HBITMAP)SendDlgItemMessage(Dlg,Item,STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)img);
    if(hReturn)
    {
                DeleteObject(hReturn);
    }
    Last edited by novacain; 12-10-2010 at 10:05 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

  15. #45
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34
    Well thanks for the help to both.

    For once, I've tried this:

    Code:
    BOOL SetStaticImg(HWND Dlg, INT Item, PCHAR ImageFile)
      { HANDLE img;
         img = LoadImage(NULL,ImageFile,IMAGE_BITMAP,0,0,LR_DEFAULTSIZE);
         if (!img)
          return FALSE;
        SendDlgItemMessage(Dlg,Item,SCM_SETIMAGE,IMAGE_BITMAP,(LPARAM)img);
        return TRUE; }
    Replacing "ImageFile" with the path to the file, and even tried changing "Item" with the control handle but still not working(it doesn't throw any errors, it just doesn't work).

    Also I've tried:
    Code:
    SendMessage(GetDlgItem(hWnd, IDC_CONTROL), STM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM)IDB_IMAGE1 );
    And it doesn't work either, again without any error.

    So I'll clarify everything, hope it helps:

    .rc:
    Code:
    CONTROL         "",IDC_STATIC12, WC_STATIC, SS_BITMAP | 0x00000040, 14, 18, 102, 55
    
    IDB_IMAGE1       BITMAP         "C:\\Users\\Diego\\Desktop\\Ciudad Mejorada WinAPI\\animage.bmp"
    resource.h:
    Code:
    #define IDB_IMAGE1 308
    
    #define IDC_STATIC12 3072
    And, with this, I'm just trying to pop up the image in the control box (IDC_STATIC12). But I'm tired of tryin with any kind of SendMessage, SendDlgItemMessage, LoadImage, LoadBitmap, etc. which doesn't say "ok there's an error here", no, it works, but it just won't pop up the bmp...

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