How do I get a bitmap into a dialog in a DLL?

You've hit on a known problem with bitmaps in dialogs in dlls. This also used to be a problem for icons but that appears to be working now.

First, define your bitmap in your dialog like this (notice no mention of SS_BITMAP). It is strictly text at this point. PM can handle this when loading the dialog:

Below are all the files necessary to create dllbitmp.exe and dlgdll.dll. Dlgdll has the dialog box and bitmap. Dllbitmp.exe calls DllDialog() in dlgdll.dll to bring up the dialog box from the dll's resource file...

DLLBITMP.C:

 #define  INCL_GPI
 #define  INCL_WIN
 #include <os2.h>
 #include "dllbitmp.h"

 #define FRAME_FLAGS  (FCF_TASKLIST | FCF_TITLEBAR   |
                       FCF_MENU     | FCF_SYSMENU    |
                       FCF_MINMAX   | FCF_SIZEBORDER |
                       FCF_SHELLPOSITION)
 #define CLIENT_CLASS "DllBitmp"


 INT main( VOID );
 VOID EXPENTRY DllDialog( HWND );
 FNWP wpClient;


 INT main( VOID )
 {
    HAB   hab;
    HMQ   hmq;
    QMSG  qmsg;
    HWND  hwndFrame, hwndClient;
    ULONG flFrame = FRAME_FLAGS;

    hab = WinInitialize( 0 );
    hmq = WinCreateMsgQueue( hab, 0 );
    WinRegisterClass( hab, CLIENT_CLASS, wpClient, 0, 0 );
    hwndFrame = WinCreateStdWindow( HWND_DESKTOP, WS_VISIBLE,
                                    &flFrame,CLIENT_CLASS, NULL,
                                    0,NULLHANDLE, ID_RESOURCES,
                                    &hwndClient );
    while( WinGetMsg( hab, &qmsg, NULLHANDLE, 0, 0 ) )
       WinDispatchMsg( hab, &qmsg );

    WinDestroyWindow( hwndFrame );
    WinDestroyMsgQueue( hmq );
    WinTerminate( hab );
    return 0;
 }


 MRESULT EXPENTRY wpClient( HWND hwnd, ULONG msg,
                            MPARAM mp1, MPARAM mp2 )
 {
    switch( msg )
    {
       case WM_ERASEBACKGROUND:
          return (MRESULT) TRUE;
       case WM_COMMAND:
       switch( SHORT1FROMMP( mp1 ) )
       {
          case IDM_DOIT:
          {
             DllDialog( hwnd );
             return 0;
          }
       }

       break;
    }
    return WinDefWindowProc( hwnd, msg, mp1, mp2 );
 }

DLLBITMP.H:

 #define ID_RESOURCES	1
 #define IDD_DOIT	100
 #define IDM_DOIT	110
 #define ID_BITMAP	1100
 #define ID_BITMAPID	1200

DLLBITMP.DEF:

 NAME		DLLBITMP      WINDOWAPI
 PROTMODE
 HEAPSIZE	16384
 STACKSIZE	16384

DLLBITMP.RC:

 #include <os2.h>
 #include "dllbitmp.h"


 MENU ID_RESOURCES
 {
     MENUITEM "!~DoIt", IDM_DOIT
 }

DLGDLL.C:

 #define  INCL_DOS
 #define  INCL_GPI
 #define  INCL_WIN
 #include <os2.h>
 #include "dllbitmp.h"


 FNWP wpDlg;


 VOID EXPENTRY DllDialog( HWND hwnd )
 {
    HMODULE hmod;

    DosQueryModuleHandle( "DLGDLL", &hmod );
    WinDlgBox( HWND_DESKTOP, hwnd, wpDlg, hmod, IDD_DOIT, NULL );
 }


 MRESULT EXPENTRY wpDlg( HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2 )
 {
    switch (msg)
    {
       case WM_INITDLG:
       {
          HWND    hwndBmp = WinWindowFromID( hwndDlg, ID_BITMAPID );
          HPS     hps = WinGetPS( hwndDlg );
          HBITMAP hbm;
          HMODULE hmod;

          DosQuieryModuleHandle( "DLGDLL", &hmod );
          hbm = GpiLoadBitmap( hps, hmod, ID_BITMAP, 0, 0 );
          WinSetWindowBits(hwndBmp,QWL_STYLE,SS_BITMAP,SS_BITMAP | 0x7f);
          WinSendMsg( hwndBmp, SM_SETHANDLE, MPFROMP( hbm ), NULL );
          WinSetWindowULong( hwndDlg, QWL_USER, (ULONG) hbm );
          WinReleasePS( hps );
          break;
       }
       case WM_DESTROY:
       {
          HBITMAP hbm = (HBITMAP) WinQueryWindowULong(hwndDlg,QWL_USER );
          GpiDeleteBitmap( hbm );
          break;
       }
    }
    return WinDefDlgProc( hwndDlg, msg, mp1, mp2 );
 }

DLGDLL.DLG:

 DLGTEMPLATE IDD_DOIT LOADONCALL MOVEABLE DISCARDABLE
 BEGIN
   DIALOG "", IDD_DOIT, 0, 0, 210, 154, FS_NOBYTEALIGN | FS_DLGBORDER |
              WS_VISIBLE | WS_CLIPSIBLINGS | WS_SAVEBITS, FCF_TITLEBAR
   BEGIN
       CONTROL "foo", ID_BITMAPID, 98, 56, 32, 32, WC_STATIC,
               SS_TEXT | DT_LEFT | DT_TOP | WS_VISIBLE
   END
 END

DLGDLL.DEF:

 LIBRARY	DLGDLL		INITINSTANCE	TERMINSTANCE
 PROTMODE
 CODE		LOADONCALL
 DATA		LOADONCALL	MULTIPLE	NONSHARED
 EXPORTS	DllDialog

DLGDLL.RC:

 #include <os2.h>
 #include "dllbitmp.h"


 BITMAP  ID_BITMAP "dlgdll.bmp"


 rcinclude dlgdll.dlg

MAKEFILE:

 all: dlgdll.dll dllbitmp.exe

 dlgdll.dll: $*.obj $*.res
     link386 /NOI /NOE /MAP /DE /NOL $*, $*.dll,, os2386, $*
     rc $*.res $*.dll
     implib $*.lib $*.def

 dllbitmp.exe: $*.obj $*.def $*.res
     link386  /NOI /NOE /MAP /DE /NOL $*,,, os2386 dlgdll, $*
     rc $*.res $*.exe

 dllbitmp.obj: $*.c
     icc /Q+ /Ss /W3 /Kbcepr /Gm- /Gd- /Ge+ /Ti+ /O- /C $*.c

 dllbitmp.res: $*.rc
     rc -r $*

 dlgdll.obj: $*.c
     icc /Q+ /Ss /W3 /Kbcepr /Gm- /Gd- /Ge- /Ti+ /O- /C $*.c

 dlgdll.res: $*.rc $*.dlg
     rc -r $*

Credit: Rick Fishman


[Back: How do I know what item was selected in a Combo box?]
[Next: How does programming PM compare to programming X?]