Announcement

Collapse
No announcement yet.

TBBUTTON structure

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • TBBUTTON structure



    Code:
    typedef struct {
      int       iBitmap;
      int       idCommand;
      BYTE      fsState;
      BYTE      fsStyle;
    #ifdef _WIN64
      BYTE      bReserved[6];
    #else 
    #if defined(_WIN32)
      BYTE      bReserved[2];
    #endif 
    #endif 
      DWORD_PTR dwData;
      INT_PTR   iString;
    } TBBUTTON, *PTBBUTTON, *LPTBBUTTON;
    I have defined as:

    Code:
    DWORD_PTR = DWORD;
    INT_PTR = INT;
    TBBUTTON = MemoryEx.DefineStruct{
      INT       "iBitmap";
      INT       "idCommand";
      BYTE      "fsState";
      BYTE      "fsStyle";
      BYTE      "bReserved";
      DWORD_PTR "dwData";
      INT_PTR   "iString";
    }
    and I use it like so:

    Code:
    AToolBar.AddButtonEx = function(ID,Txt,Img,Typ)
     local TB_ADDBUTTONS = 0x414;
     local TBSTATE_ENABLED = 4;
     local TBSTYLE_BUTTON = 0;
     local TBSTYLE_SEP = 1;
     local BTNS_WHOLEDROPDOWN = 0x0080;
     local BTNS_SHOWTEXT = 0x0040;
     local lpBuff = MemoryEx.Allocate(MemoryEx.StructSize(TBBUTTON) + 100);
     if(lpBuff)then
      local hStruct = MemoryEx.AssignStruct(lpBuff + 50, TBBUTTON);
      if(hStruct)then
       hStruct.iBitmap = Img;
       hStruct.idCommand = ID;
       hStruct.fsState = TBSTATE_ENABLED;
       if Typ == 1 then
        hStruct.fsStyle = TBSTYLE_BUTTON;
       elseif Typ == 2 then
        hStruct.fsStyle = TBSTYLE_SEP;
       elseif Typ == 3 then
        hStruct.fsStyle = BTNS_WHOLEDROPDOWN;
       end
       hStruct.bReserved = 0;
       hStruct.dwData = 0;
       local n = String.Length(Txt) + 1
       local m = MemoryEx.Allocate(n)
       MemoryEx.String(m,-1,MEMEX_ASCII,Txt)
       hStruct.iString = m
       local poi = hStruct:GetPointer()
       if tonumber(User32Library.SendMessageA(AToolBar.Handle,TB_ADDBUTTONS,1,poi)) == 0 then
        MemoryEx.Free(lpBuff);
        MemoryEx.Free(m);
        hStruct:Close();
        return false, "Can't add button"
       else
        MemoryEx.Free(lpBuff);
        MemoryEx.Free(m);
        hStruct:Close();
        return true, "OK"
       end
      else
       MemoryEx.Free(lpBuff);
       return false, "Can't assign structure"
      end
     else
      return false, "Can't create buffer"
     end
    end;
    Everything but the text appears to work so no button labels show nor tooltips so I assume its an issue with handling the iString, MemoryEx checks out as creating the buffer and having the text in it so am I defining this structure properly?

    Second question about this structure is you can define more than one button at a time with it so is shown in C++

    Code:
        TBBUTTON tbButtons[numButtons] = 
        {
            { MAKELONG(STD_FILENEW,  ImageListID), IDM_NEW,  TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"New" },
            { MAKELONG(STD_FILEOPEN, ImageListID), IDM_OPEN, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"Open"},
            { MAKELONG(STD_FILESAVE, ImageListID), IDM_SAVE, 0,               buttonStyles, {0}, 0, (INT_PTR)L"Save"}
        };
    so how do I, if I can, add in the other values to the MemoryEx structure table? (messed about with various [?] options but just get crashes)?.

  • #2
    Something like this?

    Code:
    DWORD_PTR   = DWORD;
    INT_PTR     = INT;
    TBBUTTON    = MemoryEx.DefineStruct{
      INT       "iBitmap";
      INT       "idCommand";
      BYTE      "fsState";
      BYTE      "fsStyle";
      BYTE      ("bReserved", 2);
      DWORD_PTR "dwData";
      INT_PTR   "iString";
    }
    
    -- MAKELONG
    function MAKELONG(low, high)
        return Bitwise.Or(Bitwise.ASL(high, 16), low);
    end
    
    
    --[[
        The function below will generate the array displayed here, but it will not do
        anything with the reserved field (because you shouldn't.). So ommit the {0} value.
        
        IGNORE THE {0}!
        
        TBBUTTON tbButtons[numButtons] = 
        {
            { MAKELONG(STD_FILENEW,  ImageListID), IDM_NEW,  TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"New" },
            { MAKELONG(STD_FILEOPEN, ImageListID), IDM_OPEN, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"Open"},
            { MAKELONG(STD_FILESAVE, ImageListID), IDM_SAVE, 0,               buttonStyles, {0}, 0, (INT_PTR)L"Save"}
        };
    ]]
    
    -- Creates a memory array of TBBUTTON structures, free the result of
    -- this function with TBBUTTON_FreeArray(lpResult)
    function TBBUTTON_Array(tableTBBUTTON)
    	local count = #tableTBBUTTON;
    	if(count < 1)then
    		return nil;
    	end
    	
    	local ssize = MemoryEx.StructSize(TBBUTTON);
    	local lpMem = MemoryEx.Allocate((count * ssize) + 4);
    	local offs  = 0;
    	if(lpMem)then
    		MemoryEx.UnsignedInteger(lpMem, count);
    		
    		for i, v in pairs(tableTBBUTTON)do
    			local hButton = MemoryEx.AssignStruct((lpMem + offs + 4), TBBUTTON);
    			if(hButton)then
    				hButton.iBitmap     = v[1];
    				hButton.idCommand   = v[2];
    				hButton.fsState     = v[3];
    				hButton.fsStyle     = v[4];
    				hButton.dwData      = v[5];
    				
    				if(type(v[6]) == "string")then
    					local pszString     = MemoryEx.Allocate(v[6]:len() + 1);
    					if(pszString)then
    						MemoryEx.String(pszString, -1, MEMEX_ASCII, v[6]);
    						hButton.iString = pszString;
    					end
    				end
    				
    				hButton:Close();
    			end
    			
    			offs = (offs + ssize);
    		end
    		
    		return (lpMem + 4);
    	end
    end;
    
    function TBBUTTON_FreeArray(lpArray)
    	local pOrig = (lpArray - 4);
    	local count = MemoryEx.UnsignedInteger(pOrig);
    	local offs  = 0;
    	local ssize = MemoryEx.StructSize(TBBUTTON);
    	
    	if(count < 1)then
    		return nil;
    	end
    	
    	for i = 1, count do
    		local hButton = MemoryEx.AssignStruct((lpArray + offs), TBBUTTON);
    		if(hButton)then
    			if(hButton.iString > 0)then
    				MemoryEx.Free(hButton.iString);
    			end
    			
    			hButton:Close();
    		end
    		
    		offs = (offs + ssize);
    	end
    	
    	return MemoryEx.Free(pOrig);
    end;
    Example usage:
    Code:
    -- example
    local lpTBBUTTONarr = TBBUTTON_Array{
    	{MAKELONG(1, 2), 3, 4, 5, 0, "New"},
    	{MAKELONG(1, 2), 3, 4, 5, 0, "Open"},
    	{MAKELONG(1, 2), 3, 4, 5, 0, "Save"},
    };
    
    if(lpTBBUTTONarr)then
    	TBBUTTON_FreeArray(lpTBBUTTONarr);
    end
    Untested, test first!
    Bas Groothedde
    Imagine Programming :: Blog

    AMS8 Plugins
    IMXLH Compiler

    Comment


    • #3
      Wow, changing:

      Code:
      BYTE      "bReserved";
      to

      Code:
      BYTE      ("bReserved", 2);
      gave the button text and tooltips straight away, thanks, on to testing the TBBUTTON_Array..............

      Comment


      • #4
        That's because on WIN32, the bReserved field in the structure is a BYTE array with a size of 2. If you don't specify this, it means the structure is one byte smaller and all the following fields are not aligned correctly any more.
        Bas Groothedde
        Imagine Programming :: Blog

        AMS8 Plugins
        IMXLH Compiler

        Comment

        Working...
        X