Thread: Simple WinAPI code problem.

  1. #46
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Ok, so you have your image in your resources.... That needs a slight change in procedure as we now need to load the image from your application instance instead of a disk file.

    First step all the way back to your program entry point...
    Make a global variable from the hInstance parameter. Generally I put this, the main window handle and other frequently used bits. into a small global.h header that I include in all project source files.

    Code:
    // global.h
    #ifndef PROJ_GLOBAL
    #define PROJ_GLOBAL
    
    HINSTANCE gInst;
    HWND hMain;
    
    // other globals here
    
    #endif // PROJ_GLOBAL
    Code:
    // program .c file...
    #include "global.h"
    
    // entry point
    INT CALLBACK WindMain(HINSTANCE hInst, HINSTANCE pInst, LPSTR CLine,INT CShow)
      {  gInst = hInst;
    
    // and the rest
    
      return 0; }
    Despite the common prohibition against global variables, this is far better than the time wasting alternative of having to rediscover the program's instance handle in 750 different places in your code.

    Now for the image problem....

    Code:
    // top of dialog.c
    #include "global.h"
    
    // and to load the image
    BOOL SetStaticImg(HWND Dlg, INT Item, INT ImageFile)
      { HANDLE img;
        img = LoadImage(gInst, MAKEINTRESOURCE(ImageFile), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
        if (!img)
          return FALSE;
        SendDlgItemMessage(Dlg,Item,SCM_SETIMAGE,IMAGE_BITMAP,(LPARAM)img);
        return TRUE; }
    Which you would call as...
    Code:
    If (!  SetStaticImg(HDialog,IDC_STATIC, IDB_BITMAP)  )
      Beep(1000,250);
    What necessitates all that change is that with the image in the resources it is actually part of your program. You need to tell LoadImage where to look (first parameter) as well as the resource ID of the image...

    Yes, the Beep is a diagnostic you will want to take out later. It will screech at you if it fails to load the image.

    Novacain also makes a good point that with this construct, if you are setting that image more than once, you should free the previous image from the static control... So...

    Code:
    BOOL SetStaticImg(HWND Dlg, INT Item, INT ImageFile)
      {  HANDLE img;                     // new image
         HANDLE pimg;                   // previous image
    
        img = LoadImage(gInst, MAKEINTRESOURCE(ImageFile), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
        if (!img)
          return FALSE;
    
        pimg = (HANDLE) SendDlgItemMessage(Dlg,Item,SCM_SETIMAGE,IMAGE_BITMAP,(LPARAM)img);
        if (pimg)
           DeleteObject(pimg);
        return TRUE; }
    Like I said... you may need to do more work on this.
    Last edited by CommonTater; 12-11-2010 at 11:25 AM.

  2. #47
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34
    I've tried a million different ways, but it doesn't get past the BOOL.
    Correct me if I'm wrong, but shouldn't there be mentioned the Picture Control Handle (like IDC_PICCONTROL) and the declared image(IDB_IMAGE)? Because they aren't and I can't imagine how it chooses which picture to display and where :S.

    And also... you said that having the picture in the resources takes more work to load it than just loading it from a random place in the hard disk... how come? that means that if I just cut and paste it in the desktop, the procedure to load it will be easier? (sorry for my ignorance).

  3. #48
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Pecado View Post
    I've tried a million different ways, but it doesn't get past the BOOL.
    Correct me if I'm wrong, but shouldn't there be mentioned the Picture Control Handle (like IDC_PICCONTROL) and the declared image(IDB_IMAGE)? Because they aren't and I can't imagine how it chooses which picture to display and where :S.

    And also... you said that having the picture in the resources takes more work to load it than just loading it from a random place in the hard disk... how come? that means that if I just cut and paste it in the desktop, the procedure to load it will be easier? (sorry for my ignorance).
    Ok... no more cryptic responses... EXACTLY what are you trying to accomplish... code samples would help.

  4. #49
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34
    I have this dialog:

    Code:
    BOOL CALLBACK ConcesDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {switch(Message)
        {case WM_INITDIALOG:
         SendDlgItemMessage(hwnd, IDC_COMBOBOX, CB_ADDSTRING, 0, (LPARAM)st1);
         SendDlgItemMessage(hwnd, IDC_COMBOBOX, CB_ADDSTRING, 0, (LPARAM)st2);
         SendDlgItemMessage(hwnd, IDC_COMBOBOX, CB_ADDSTRING, 0, (LPARAM)st3);
        return 1;
        case WM_COMMAND:
        switch(LOWORD(wParam))
        {
               case IDC_COMBOBOX:
                    switch (HIWORD(wParam))
                      {case CBN_SELENDOK :
                          COMBOBOXIDS(hwnd,LOWORD(wParam)); return 0;
                       default: return 0;}
               case IDCANCEL:
                    EndDialog(hwnd, 0);
                    return 1;
        }
        return 1;
        default: return FALSE;}
    return TRUE;}
    From the bold type function, goes to here:

    Code:
    VOID COMBOBOXIDS(HWND hwnd,int List)
       {int id;
        id = SendDlgItemMessage(hwnd,List,CB_GETCURSEL,0,0);
        Beep(700,100);
        if (carid < 1)
           {CheckDlgButton(hwnd,List - 4,0);
            CheckDlgButton(hwnd,List - 3,0);
            CheckDlgButton(hwnd,List - 2,0);
            CheckDlgButton(hwnd,List - 1,0); 
            SetDlgItemText(hwnd,List + 1,NULL);}
        else
          {CheckDlgButton(hwnd,List - 4,1);}
    
      switch(id)
      {case 0:SetDlgItemText(hwnd,IDC_STATIC9,"This is case 0."); break;
       case 1:SetDlgItemText(hwnd,IDC_STATIC9,"This is case 1."); break;
       case 2:SetDlgItemText(hwnd,IDC_STATIC9,"This is case 2."); break;}}
    What I'm trying to do is, in a picture control, display a diferent .bmp depending on the selected combobox item. So, basically I would like to add, in each case of the switch(id) a function like "LoadBitmap" or whichever is it that is most suitable to load a bitmap. If that is a problem, even pressing a button would be just fine. My problem is not where, but how...
    And I've been trying for days already but it just won't work, though I am able to set a bitmap in the .rc (like one that it is "born" with).
    If you need any more info let me know.
    Last edited by Pecado; 12-11-2010 at 08:12 PM.

  5. #50
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Pecado View Post
    I have this dialog:
    Code:
    VOID COMBOBOXIDS(HWND hwnd,int List)
       {int id;
        id = SendDlgItemMessage(hwnd,List,CB_GETCURSEL,0,0);
        Beep(700,100);
        if (carid < 1)
           {CheckDlgButton(hwnd,List - 4,0);
            CheckDlgButton(hwnd,List - 3,0);
            CheckDlgButton(hwnd,List - 2,0);
            CheckDlgButton(hwnd,List - 1,0); 
            SetDlgItemText(hwnd,List + 1,NULL);}
        else
          {CheckDlgButton(hwnd,List - 4,1);}  
    
       switch(id)
      {case 0:SetDlgItemText(hwnd,IDC_STATIC9,"This is case 0."); break;
       case 1:SetDlgItemText(hwnd,IDC_STATIC9,"This is case 1."); break;
       case 2:SetDlgItemText(hwnd,IDC_STATIC9,"This is case 2."); break;}}
    Ok first off... why do you have stuff from my examples in there? That example clears a row of checkboxes if you select the first list item, which says "_reset_" in my code. Do you actually have buttons at those id numbers? If not you're producing a stream of runtime errors.

    Not to be rude... but that's what happens when we cut and paste without understanding.

    What I'm trying to do is, in a picture control, display a diferent .bmp depending on the selected combobox item. So, basically I would like to add, in each case of the switch(id) a function like "LoadBitmap" or whichever is it that is most suitable to load a bitmap. If that is a problem, even pressing a button would be just fine. My problem is not where, but how...
    And I've been trying for days already but it just won't work, though I am able to set a bitmap in the .rc (like one that it is "born" with).
    If you need any more info let me know.
    Ok... not to panic... if you are using a picture control... look up it's styles and parameters and adjust accordingly. Windows controls all have their own constants and cross pollination most often leads to reproductive failure

    First thing, there are two controls used for pictures... the Animation Control and the Static Control... look them up in the SDK ... unless you are uploading an animated GIF, you want a Static Control.

    For the static control be sure to set the SS_BITMAP style.

    Then you should be able to use LoadImage() in your switch and the STM_SETIMAGE message after you have a handle to change the picture... as I showed you.

    Something like....

    Code:
    VOID ChangeImage(HWND hwnd,int List)
       {int        idx;
         HBITMAP hbm = NULL;
         HBITMAP hbmo;
        idx = SendDlgItemMessage(hwnd,List,CB_GETCURSEL,0,0);
        if (idx < 0)    // guard for no selection
          return;
        switch(idx)
         {  case 0:
               hbm = LoadImage(gInst,MAKEINTRESOURCE(IDB_IMAGE1),IMAGE_BITMAP,0,0,LR_DEFAULTSIZE);
               break;
            case 1:
               hbm = LoadImage(gInst,MAKEINTRESOURCE(IDB_IMAGE2),IMAGE_BITMAP,0,0,LR_DEFAULTSIZE);
               break;
           case 2:
               hbm = LoadImage(gInst,MAKEINTRESOURCE(IDB_IMAGE3),IMAGE_BITMAP,0,0,LR_DEFAULTSIZE);
               break;
           default : 
               return; }
           if (!hbm)
             return; 
           hbmo = SendDlgItemMessage(hwnd, List,STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hbm);
           if (hbmo)
             DeleteObject(hbmo);   }
    This won't be exact... you will need to change the image ids, and make sure youhave a global instance handle... before anything is going to happen. But it should be pretty close....
    provided you are using a static control to display the image!

    If this doesn't work, I'm going to step back and aske the others to chip in. I'm fast running out of ideas....
    Last edited by CommonTater; 12-11-2010 at 09:53 PM.

  6. #51
    Registered User Pecado's Avatar
    Join Date
    Sep 2010
    Posts
    34
    Ok first off... why do you have stuff from my examples in there? That example clears a row of checkboxes if you select the first list item, which says "_reset_" in my code. Do you actually have buttons at those id numbers? If not you're producing a stream of runtime errors.

    Not to be rude... but that's what happens when we cut and paste without understanding.
    Yes I know. I just thought that, as it said that that part of the code was necessary to clear the data if nothing was selected, it was needed for the code to work. Probably not now, but eventually I would start understanding everything better and then adjust everything to my needs. I'm just beginning and trying to get the hang of this, I'll make sure to use my own code in the future... and sorry if it annoyed you in some way..

    Anyway, going back to the cursed .bmp... I am using a Static Control, it has the SS_BITMAP style, but still the .bmp doesn't work with the LoadImage commands.
    Listen, I must be doing something (or things) wrong because it is impossible that it "just won't work". So, I don't want to bother you with this problem anymore, (sincerely I am frustrated with this ) I'll just keep in mind all the info you gave me and in the future, once I get more used to this, I'll come back to the problem.

  7. #52
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Pecado View Post
    Yes I know. I just thought that, as it said that that part of the code was necessary to clear the data if nothing was selected, it was needed for the code to work.
    Yes... in my code, not yours...

    Probably not now, but eventually I would start understanding everything better and then adjust everything to my needs. I'm just beginning and trying to get the hang of this, I'll make sure to use my own code in the future... and sorry if it annoyed you in some way..
    No worries... just Papa Tater givng the kids a little cuff when they get out of line.

    My first 6 weeks or so trying to "get" windows was pure frustration. I don't think I wrote a single line of working code the first week, the compiler was threatening to move out on me the end of the second week... But the light does slowly go on and soon enough you C Windows... But, of course, you never stop learning.

    Really, you're doing just fine. Nobody learns this in a couple of days.

    A friend of mine once commented that "Windows is it's own thing... it's just coincidence that we script it in C". He was right.

    Anyway, going back to the cursed .bmp... I am using a Static Control, it has the SS_BITMAP style, but still the .bmp doesn't work with the LoadImage commands.
    Well there's only so much that can go wrong there...
    • The bmp is not actually in the resources.

    • It's not in simple BMP format

    • You have it's identifier wrong

    • You don't have a valid global instance handle


    Listen, I must be doing something (or things) wrong because it is impossible that it "just won't work".
    The sad thing is that, like usual, when you do figure it out, it will be something embarassingly simple.

    So, I don't want to bother you with this problem anymore, (sincerely I am frustrated with this ) I'll just keep in mind all the info you gave me and in the future, once I get more used to this, I'll come back to the problem.
    I was thinking you might want to give yourself a couple of days off, then come back to it with a clearer eye.

    One thing I can promise you... it can be done...

    Attachment 10246
    Last edited by CommonTater; 03-16-2011 at 11:52 AM.

  8. #53
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by Pecado View Post
    [CODE]
    CONTROL "",IDC_STATIC12, WC_STATIC, SS_BITMAP | 0x00000040, 14, 18, 102, 55
    [CODE]
    What is the 0x00000040 for? (what style is it adding? try removing it).

    EDIT: it is SS_REALSIZECONTROL (resizing the image to fit the control), which is undefined in some versions of the SDK.

    After each call add a call to GetLastError(). If the return is not zero (ERROR_SUCCESS) look up what went wrong.
    Last edited by novacain; 12-12-2010 at 11:45 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

  9. #54
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by CommonTater View Post
    Code:
           hbmo = SendDlgItemMessage(hwnd, List,STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hbm);
    'List' is the combobox's ID, not the picture control's....
    Last edited by novacain; 12-13-2010 at 02:29 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

  10. #55
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by novacain View Post
    'List' is the combobox's ID, not the picture control's....
    OOPS... my bad.

    Nice catch, by the way...

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