ListView Loading Images BMP, PNG, GIF, JPEG, WMF, ICO, and EMF Files Natively (pure WINAPI)

Most Win32 API developers use a static control (with style SS_ICON or SS_BITMAP)to load bitmap and icon files. To advance the support for more image formats, some use third-party libraries such as CXImage (as far I remember the name). Wouldn't it be better to use native control and routines to load BMP, PNG, GIF, JPEG, WMF, ICO, and EMF files in Windows programs? I hope you say yes!

Note: The progrm must be linked with OLE32 and comctl32 library files.

Okay, I am not in favor of putting in huge amounts of theory, so I'll get started.

Assumptions

It is assumed that you already know some about the CreateWindow and CreateWindowEx WinAPI functions. I used the d_hwnd variable in code; it is the dialog's handle of our (the main window listview control is created at). Also, I used the l_hwnd variable in code; it is the handle of your listview control.

Core of the Article

1. First, create a listview:

HWND l_hwnd = CreateWindowEx(WS_EX_STATICEDGE,
   WC_LISTVIEW,"",
   WS_CHILD,
   0,0,200,300,
   d_hwnd,(HMENU)200,
   GetModuleHandle(NULL),
   NULL
);
//to turn the listview transparent, remove the // from the
//following two lines
//ListView_SetTextBkColor(l_hwnd,CLR_NONE);
//ListView_SetBkColor(l_hwnd,CLR_NONE);
assert(l_hwnd != NULL);
Once the listview window has been created, you can load image in it. Alternatively, you may have a dialog in resources that already has a listview on it. If so, skip this step.

2. Load the external Image file from the Internet by its URL.

LVBKIMAGE IBBkImg;
ZeroMemory(&IBBkImg,sizeof(LVBKIMAGE));

IBBkImg.ulFlags=LVBKIF_SOURCE_URL | LVBKIF_STYLE_TILE;

//if you want the image not to have a tile, remove the style
//LVBKIF_STYLE_TILE

IBBkImg.pszImage="C:\\my_image.bmp";
//you can replace C:\\my_image.bmp with any working image URL
//from the Internet.
//Try codeguru logo http://www.codeguru.com/img/logo.gif
OleInitialize(NULL); //Initialize the OLE libraries
//now load image
SendMessage (l_hwnd,LVM_SETBKIMAGE,0,(LPARAM)(LPLVBKIMAGE) &IBBkImg);

Load image from resources:

A res:// protocol will be used here to load the image from your resources. You will have to format a string for the pszImage field of the LVBKIMAGE structure, so that it loads from the resources of your EXE file.

First,you need the ID of the resource (an integer); then, you must know either that it is an icon file or an image. The format of the string that will be assigned to pszImage looks like this:

//...... same as above

IBBkImg.pszImage="res://C:\\myprog.exe/#2/#101";

//...... same as above

where C:\\myprog.exe is the current program filename, #2 is type of resource (you are loading a image, so you will use #2). To load and icon, you will have to use #3. #101 is the ID of our image resource to load.

To obtain the current application name, look into MSDN for GetModuleFileName.

Load the image from an external EXE or DLL file:

For this purpose, either you will have to format a string to load from resources of an external executable, DLL, or OCX file. Simply change C:\\myprog.exe to the absolute path of another EXE or DLL file, and all is done.

I tried loading a bitmap (ID 1047) from the resources of an external EXE file, winhlp32.exe, that is found in the Windows folder (in Windows XP; I'm am not sure about others). So, my formated string became "res://C:\\WINDOWS\\winhlp32.exe/#2/#1047" and code became:

IBBkImg.pszImage="res://C:\\WINDOWS\\winhlp32.exe/#2/#1047";

That's all.

I saw a big need for this tutorial, and I was one of the searchers looking for an easy way to load images in a listview control. Now, your listview is turned into a fully functional picture box that can be used to create a picture album or a compiled e-book. It's up to you. Let me know if anything goes wrong.



Comments

  • ListView Loading Images BMP, PNG, GIF, JPEG...

    Posted by Uvieta on 10/06/2008 08:36pm

    I think there's something wrong in my program but don't know what is it. I have a dialog in my resources that already has a list view control (in a LRESULT CALLBACK WndProc). When the program runs, it shows the dialog and the control but doesn't show the image.
    
    
    
    Platform:
    
    
    
    rgonzalez@aya-rgonzalez /
    
    $ gcc -v
    
    Reading specs from /usr/lib/gcc/i686-pc-cygwin/3.4.4/specs
    
    Configured with: /usr/build/package/orig/test.respin/gcc-3.4.4-3/configure --verbose --prefix=/usr -
    
    -exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man
    
    --infodir=/usr/share/info --enable-languages=c,ada,c++,d,f77,pascal,java,objc --enable-nls --without
    
    -included-gettext --enable-version-specific-runtime-libs --without-x --enable-libgcj --disable-java-
    
    awt --with-system-zlib --enable-interpreter --disable-libgcj-debug --enable-threads=posix --enable-j
    
    ava-gc=boehm --disable-win32-registry --enable-sjlj-exceptions --enable-hash-synchronization --enabl
    
    e-libstdcxx-debug
    
    Thread model: posix
    
    gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
    
    
    
    Thanks in advance for your help, please Ali Imran or another guru :-)
    
    ==================================================================
    
    
    
    This is how I build and compile...
    
    
    
    Para hacer dlg1_res.o:
    
    windres -o dlg1_res.o dlg_png.rc
    
    
    
    Para hacer dlg_png.o:
    
    gcc -c dlg_png.c
    
    
    
    gcc -o dlg_png dlg_png.o dlg1_res.o comctl32.lib OLE32.LIB -mwindows
    
    
    
    */
    
    
    
    BOOL CALLBACK dlgPng(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    
    {
    
    
    
    	switch(Message)
    
    	{
    
    		case WM_INITDIALOG:
    
        {
    
          InitCommonControls();
    
        
    
          LVBKIMAGE IBBkImg = {0};
    
          
          IBBkImg.ulFlags = LVBKIF_SOURCE_URL;
          IBBkImg.pszImage = "C:\\min_nep.png";
    
          IBBkImg.xOffsetPercent = 40;
    
          IBBkImg.yOffsetPercent = 60;
    
          OleInitialize(NULL);
    
          hList = GetDlgItem(hwnd, IDC_LIST); /* get the ID of the ListView */
    
          
    
          SendMessage (hList, LVM_SETBKIMAGE, 0, (LPARAM)(LPLVBKIMAGE) &IBBkImg);
    
        }
    
    		break;
    
    		case WM_COMMAND:
    
    			switch(LOWORD(wParam))
    
    			{
    
    				case IDOK:
    
            
    
              EndDialog(hwnd, IDOK);
    
    				break;
    
    				case IDCANCEL:
    
    					EndDialog(hwnd, IDCANCEL);
    
    				break;
    
    			}
    
    		break;
    
    		default:
    
    			return FALSE;
    
    	}
    
    	return TRUE;
    
    }

    Reply
  • Great

    Posted by hewangping on 08/08/2006 10:00pm

    Thanks a lot. That's what I've searched for these days.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: August 20, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT When you look at natural user interfaces as a developer, it isn't just fun and games. There are some very serious, real-world usage models of how things can help make the world a better place – things like Intel® RealSense™ technology. Check out this upcoming eSeminar and join the panel of experts, both from inside and outside of Intel, as they discuss how natural user interfaces will likely be getting adopted in a wide variety …

  • Protecting business operations means shifting the priorities around availability from disaster recovery to business continuity. Enterprises are shifting their focus from recovery from a disaster to preventing the disaster in the first place. With this change in mindset, disaster recovery is no longer the first line of defense; the organizations with a smarter business continuity practice are less impacted when disasters strike. This SmartSelect will provide insight to help guide your enterprise toward better …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds