The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: ibtjc4ever on July 25, 2009, 06:17:47 PM

Title: Toolbar - TB_SETIMAGELIST; ERROR_NOT_ENOUGH_MEMORY
Post by: ibtjc4ever on July 25, 2009, 06:17:47 PM
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.
Title: Re: Toolbar - TB_SETIMAGELIST; ERROR_NOT_ENOUGH_MEMORY
Post by: donkey on July 26, 2009, 09:29:41 AM
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...
Title: Re: Toolbar - TB_SETIMAGELIST; ERROR_NOT_ENOUGH_MEMORY
Post by: MichaelW on July 26, 2009, 09:53:55 AM
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.
Title: Re: Toolbar - TB_SETIMAGELIST; ERROR_NOT_ENOUGH_MEMORY
Post by: ibtjc4ever on July 26, 2009, 02:58:19 PM
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
Title: Re: Toolbar - TB_SETIMAGELIST; ERROR_NOT_ENOUGH_MEMORY
Post by: Squeeto on August 16, 2009, 03:12:39 PM
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.
Title: Re: Toolbar - TB_SETIMAGELIST; ERROR_NOT_ENOUGH_MEMORY
Post by: donkey on August 17, 2009, 04:51:41 AM
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
Title: Re: Toolbar - TB_SETIMAGELIST; ERROR_NOT_ENOUGH_MEMORY
Post by: Squeeto on August 17, 2009, 06:44:22 PM
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.

Title: Re: Toolbar - TB_SETIMAGELIST; ERROR_NOT_ENOUGH_MEMORY
Post by: Squeeto on August 18, 2009, 10:55:53 PM
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 :)
Title: Re: Toolbar - TB_SETIMAGELIST; ERROR_NOT_ENOUGH_MEMORY
Post by: xandaz on June 17, 2010, 06:02:44 PM
    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