I'm trying to use the standard bitmaps on a toolbar control via an image list. The image list is created successfully, but when I send the message "TB_SETIMAGELIST" the return value is zero and "GetLastError" returns error code '8', which according to MSDN's documentation is described as "Not enough storage is available to process this command." Has anyone experienced this error when trying to set images for a toolbar control. I also tried using the "TB_LOADIMAGES" message and I get the same error.
Much needed guidance concerning this error is order.
Thanks guys.
Kevin G Smith - Terrytown, La.
First off, NULL is a valid return value for that message, it simply means that there is no image list previously associated with the toolbar. Very few messages support error codes and GetLastError will generally return less than useful information, for example it may return the last error code from a function that resides in some Windows DLL attached to your program and error 8 is a common one that does not always signal a massive problem. For example it is sometimes returned inside NTDLL to indicate that an array needs to be expanded, the array is expanded internally by Windows but the error is not cleared.
If you could post a bit of the relevant code it would be helpful in diagnosing your problem...
It might be useful to use the SetLastError function to set the last error code to zero (ERROR_SUCCESS) before sending the message, and then see what GetLastError returns.
Thanks guys for the input. Here's the routine that I'm using to setup the toolbar:
CreateToolBar PROC hndWindow:HWND
LOCAL strctTlBrBtn:TBBUTTON
INVOKE CreateWindowEx, NULL, OFFSET mStrTOOLBARCLASSNAME,
NULL, WS_CHILD + WS_VISIBLE, 0, 0, 0, 0, hndWindow, NULL,
mHndAppInst, NULL
MOV mHndToolBar, EAX
INVOKE ImageList_Create, 16, 16, ILC_MASK, 0, 5
INVOKE SendMessage, mHndToolBar, TB_SETIMAGELIST, 0, EAX
INVOKE SendMessage, mHndToolBar, TB_LOADIMAGES,
IDB_STD_SMALL_COLOR, HINST_COMMCTRL
MOV strctTlBrBtn.iBitmap, STD_FILESAVE
MOV strctTlBrBtn.idCommand, IDTB_Save
MOV strctTlBrBtn.fsState, TBSTATE_ENABLED
MOV strctTlBrBtn.fsStyle, BTNS_AUTOSIZE
MOV strctTlBrBtn.bReserved, 0
MOV strctTlBrBtn.dwData, 0
MOV strctTlBrBtn.iString, OFFSET mStrSave
INVOKE SendMessage, mHndToolBar, TB_BUTTONSTRUCTSIZE,
SIZEOF TBBUTTON, 0
INVOKE SendMessage, mHndToolBar, TB_ADDBUTTONS, 1,
ADDR strctTlBrBtn
RET
CreateToolBar ENDP
I studied the example directly from MSDN (http://msdn.microsoft.com/en-us/library/bb760446(VS.85).aspx) and I've seen other examples on the internet but, nowhere does anyone mention anything about memory contraints or what-not. According to the example on MSDN, I can't see what I'm doing wrong or what I'm missing.
Thanks,
Kevin G Smith - Terrytown, La. USA
You have
INVOKE ImageList_Create, 16, 16, ILC_MASK, 0, 5
but I see that the MS example shows
.... numButtons, 0);
I still think that you've got it right though. Maybe the example has another fault.
Sorry, it is beyond me.
I have always had problems with Imagelist_Create when setting the initial number of buttons to zero. Try putting a number for cInitial and 0 or some other number for cGrow...
invoke ImageList_Create,16,16,ILC_MASK,,5,5
Edgar
I put ibtjc4ever's code in a standard template with the "ImageList_Create, 16, 16, ILC_MASK, 5, 5" change:
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\comctl32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comctl32.lib
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
CreateToolBar proto :DWORD
.const
.data
ClassName db "WinClass",0
AppTitle db "Test",0
mStrTOOLBARCLASSNAME db "ToolbarWindow32",0
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
mHndToolBar HWND ?
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
invoke ExitProcess, eax
WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hWnd:HWND
mov wc.cbSize, SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
push hInst
pop wc. hInstance
mov wc.hbrBackground, COLOR_BACKGROUND
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, OFFSET ClassName
invoke LoadIcon, NULL, IDI_APPLICATION
mov wc.hIcon, eax
mov wc.hIconSm, eax
invoke LoadCursor, NULL, IDC_ARROW
mov wc.hCursor, eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx,NULL,addr ClassName,addr AppTitle,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,300,200,NULL,NULL,\
hInst,NULL
mov hWnd, eax
invoke ShowWindow, hWnd, SW_SHOWNORMAL
invoke UpdateWindow, hWnd
.while TRUE
invoke GetMessage, addr msg, NULL, 0, 0
.BREAK .if (!eax)
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
.endw
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.if uMsg==WM_DESTROY
invoke PostQuitMessage, NULL
.elseif uMsg==WM_CREATE
invoke CreateToolBar,hWnd
.else
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
.endif
xor eax,eax
ret
WndProc endp
CreateToolBar PROC hndWindow:HWND
LOCAL strctTlBrBtn:TBBUTTON
INVOKE CreateWindowEx, NULL, OFFSET mStrTOOLBARCLASSNAME,\
NULL, WS_CHILD + WS_VISIBLE, 0, 0, 0, 0, hndWindow, NULL,\
hInstance, NULL
MOV mHndToolBar, EAX
INVOKE ImageList_Create, 16, 16, ILC_MASK, 5, 5
INVOKE SendMessage, mHndToolBar, TB_SETIMAGELIST, 0, EAX
; INVOKE SendMessage, mHndToolBar, TB_LOADIMAGES,\
; IDB_STD_SMALL_COLOR, HINST_COMMCTRL
; MOV strctTlBrBtn.iBitmap, STD_FILESAVE
; MOV strctTlBrBtn.idCommand, IDTB_Save
; MOV strctTlBrBtn.fsState, TBSTATE_ENABLED
; MOV strctTlBrBtn.fsStyle, BTNS_AUTOSIZE
; MOV strctTlBrBtn.bReserved, 0
; MOV strctTlBrBtn.dwData, 0
; MOV strctTlBrBtn.iString, OFFSET mStrSave
; INVOKE SendMessage, mHndToolBar, TB_BUTTONSTRUCTSIZE,\
; SIZEOF TBBUTTON, 0
; INVOKE SendMessage, mHndToolBar, TB_ADDBUTTONS, 1,\
; ADDR strctTlBrBtn
RET
CreateToolBar endp
end start
And to here, it makes an empty toolbar at the top. I changed his mHndAppInst to hInstance because I didn't know what to do with it.
If I uncomment the TB_LOADIMAGES line, it fails. No error messages, the program just ends.
ibtjc4ever
There is a working toolbar example in the masm directory (masm\EXAMPLE3\APPACK) that uses CreateWindowEx but without TB_LOADIMAGES or TB_SETIMAGELIST.
Well you do have to pick out the toolbar part :)
what if instead using system defined bitmaps we'd like to use our own?
I did something like this but it doesn't work. Can someone help?
inv. CreateWindowEx,NULL;addr TBClass,NULL,WS_VISIBLE+WS_CHILD,0,0,0,0,hWnd,ToolbarID,hInstance,NULL
mov hTB,eax
inv. ImageList_Create,28,28,ILC_COLOR24,6,6
mov hList,eax
inv. LoadImage,hInstance,addr Bitmap1,IMAGE_BITMAP.28,28,LR_LOADFROMFILE
push eax
inv. ImageListAdd,hList,eax,NULL
pop eax
inv. DeleteObject,eax
inv. SendMessage,hTB,TB_SETIMAGELIST,ListID,hList
inv. SendMessage,hTB,TB_SETBUTTONSTRUCTSIZE,sizeof TBBUTTON,NULL
inv. SendMessage,hTB,TB_ADDBUTONS,NoButtons,addr TBButtons
inv. SendMessage,hTB,TB_AUTOSIZE,NULL,NULL
Thanks guys. bye
Bests from x