Here is the latest code that now incorporates all of the changes that Jose has made since I posted the previous source. Looking good especially the toolbar/rebar code which is now much more compact and uses png images instead of bitmaps.
Tip:
If you are going to use for the hot imagelist the same icons that for the normal one, you can remove all the AfxGdipAddIconFromRes(hImageListHot ... and pass in the TB_SETHOTIMAGELIST message the same handle that for TB_SETIMAGELIST, i.e.
SendMessageW hToolBar, TB_SETIMAGELIST, 0, Cast(LPARAM, hImageListNormal)
SendMessageW hToolBar, TB_SETDISABLEDIMAGELIST, 0, Cast(LPARAM, hImageListDisabled)
SendMessageW hToolBar, TB_SETHOTIMAGELIST, 0, Cast(LPARAM, hImageListNormal)
Ah, yes, I will definitely do this. No need to have the extra Hot imagelist at this point. I will reuse the existing normal list as the hot list.
Paul,
Good start with WinFBE. The message crackers got me thinking of hacking the MessageCrackWizard:
http://www.codeproject.com/Articles/4948/Message-Cracker-Wizard-for-Win-SDK-Developers
To spit out Fb code but: Where is WM_NOTIFY in windowsx?
The wizard doesn't have it either???
James
> Where is WM_NOTIFY in windowsx?
It is not in windowsx.bi, but in commctrl.bi.
#define HANDLE_WM_NOTIFY(hwnd, wParam, lParam, fn) fn((hwnd), clng(wParam), cptr(NMHDR ptr, (lParam)))
It needs to be there because of the use of the NMHDR structure.
Quote
' ========================================================================================
' Process WM_CREATE message for window/dialog: frmMain
' ========================================================================================
Function frmMain_OnCreate(ByVal HWnd As HWnd, ByVal lpCreateStructPtr As LPCREATESTRUCT) As BOOLEAN
' Retrieve a reference to the CWindow class from the CREATESTRUCT structure
'Dim pCreateStruct As CREATESTRUCT Ptr = lpCreateStructPtr
'Dim pWindow As CWindow Ptr = Cast(CWindow Ptr, pCreateStruct->lpCreateParams)
' Message cracker macro expects a True to be returned for a successful
' OnCreate handler even though returning -1 from a standard WM_CREATE
' call would stop creating the window. This is just one of those Windows
' inconsistencies.
Return True
End Function
Maybe it will be a little less confussing if you use a Long and return CTrue?
' ========================================================================================
' Process WM_CREATE message for window/dialog: frmMain
' ========================================================================================
Function frmMain_OnCreate(ByVal HWnd As HWnd, ByVal lpCreateStructPtr As LPCREATESTRUCT) As LONG
' Retrieve a reference to the CWindow class from the CREATESTRUCT structure
'Dim pCreateStruct As CREATESTRUCT Ptr = lpCreateStructPtr
'Dim pWindow As CWindow Ptr = Cast(CWindow Ptr, pCreateStruct->lpCreateParams)
Return CTrue
End Function
In fact, the message cracker macro expects a true value to be returned, i.e. any value except 0, not necessarily a boolean True (-1).
I never have liked that cracking stuff, but to each his own.
For example, in this code I create a new font and store its handle in a static variable because it will be used in WM_PAINT. If I use an OnCreate function, I can't do it. Of course, I can modify the code, but why for?
STATIC hNewFont AS HFONT
SELECT CASE uMsg
CASE WM_CREATE
' // Get a pointer to the CWindow class from the CREATESTRUCT structure
DIM pCreateStruct AS CREATESTRUCT PTR = CAST(CREATESTRUCT PTR, lParam)
DIM pWindow AS CWindow PTR = CAST(CWindow PTR, pCreateStruct->lpCreateParams)
' // Create a new font scaled according the DPI ratio
IF pWindow->DPI <> 96 THEN hNewFont = pWindow->CreateFont("Tahoma", 9)
EXIT FUNCTION
If I find convenient to process the message in a separate function because the code is long, I do it, with the advantage of passing the parameters that I need, and returning the value that I want.
Also, if I want not to have to remember if I have to use HIWORD or LOWORD, i can use the aready defined macros, e.g.
CASE WM_COMMAND
SELECT CASE GET_WM_COMMAND_ID(wParam, lParam)
' // If ESC key pressed, close the application sending an WM_CLOSE message
CASE IDCANCEL
IF GET_WM_COMMAND_CMD(wParam, lParam) = BN_CLICKED THEN
SendMessageW hwnd, WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
END SELECT