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