Just curious, did you make changes to the AfxCWindowPtr for your latest #12 update? I am finding that function is now failing in my code but when I replace it with AfxCWindowOwnerPtr things work again. For example, the Find and Replace dialogs will not display correctly until the change is made.
Yes. Previously, AfxCWindowPtr did the same that AfxCWindowOwnerPtr, but after adding support for scrollable windows, an additional function was needed because the controls of the scrollable window are children of a window that, in turn, is child of the main window, and the function returned a pointer to the CWindow class of the main window instead of the one of the parent child window.
I'm sorry for not having thought that perhaps you were using it passing the handle of a child control. AfxCWindowPtr can be still used as AfxCWindowPtr(GetParent(hwnd)), or you can use AfxCWindowOwnerPtr.
Thanks Jose, no problem at all. I just needed to make a few changes. I am using the editor tonight and picking up on various inconsistencies especially related to adding/removing files to projects, etc. Hope to do a lot of testing tonight and tomorrow to stabilize everything.
I started with a scrollable main window. Then I thought that since tab pages don't offer much space for child controls, it would be useful to have the possibility of making them scrollable. And last, but not the least, I thought that it would also be useful to have a scrollable window as a child of another window (scrollable and resizable or not).
See in the capture an scrollable and resizable child dialog.
Relevant code:
' ***************************************************************************************
' // Child dialog
DIM pChildDlg AS CWindow
pChildDlg.Create(pWindow.hWindow, "", @ChildDlg_WndProc, 15, 15, , , _
WS_VISIBLE OR WS_CHILD OR WS_CLIPSIBLINGS OR WS_CLIPCHILDREN OR WS_BORDER, WS_EX_CONTROLPARENT)
pChildDlg.ClassStyle = CS_DBLCLKS
' // Set a client size big enough to display all the controls
pChildDlg.SetClientSize(310, 180)
' // Add an Edit control
DIM hEdit AS HWND = pChildDlg.AddControl("Edit", , IDC_EDIT1, "", 10, 15, 275, 23)
' // Add three radio buttons (the first one should have the WS_GROUP style)
pChildDlg.AddControl("RadioButton", , IDC_OPTION1, "Option 1", 10, 50, 75, 23, WS_GROUP)
pChildDlg.AddControl("RadioButton", , IDC_OPTION2, "Option 2", 10, 70, 75, 23)
pChildDlg.AddControl("RadioButton", , IDC_OPTION3, "Option 3", 10, 90, 75, 23)
' // Add a date time picker control
pChilddlg.AddControl("SysDateTimePick32", , IDC_DTPICKER, "", 135, 55, 150, 23)
' // Add a button
pChildDlg.AddControl("Button", , IDOK, "&Ok", 205, 140, 76, 23)
' // Create an instance of the CScrollWindow class and attach the child dialog to it
DIM pScrollChildDlg AS CScrollWindow PTR = NEW CScrollWindow(pChildDlg.hWindow)
' // Store the pointer in the class of the child dialog for later deletion
pChildDlg.ScrollWindowPtr = pScrollChildDlg
' // Shrink the client size
pChildDlg.SetClientSize(310, 110)
' // Set the focus in the first edit control
SetFocus hEdit
' ***************************************************************************************
' // Anchor the controls
DIM pLayout AS CLayout = pWindow.hWindow
pWindow.UserData(AFX_LAYOUTPTRIDX) = CAST(LONG_PTR, @pLayout)
pLayout.AnchorControl(IDCANCEL, AFX_ANCHOR_BOTTOM_RIGHT)
pLayout.AnchorControl(IDC_GROUPBOX, AFX_ANCHOR_HEIGHT_RIGHT)
pLayout.AnchorControl(IDC_COMBOBOX, AFX_ANCHOR_RIGHT)
' // Anchor the child CWindow
pLayout.AnchorControl(pChildDlg.hWindow, AFX_ANCHOR_HEIGHT_WIDTH)
' // We could also anchor the child controls of this window with
' // DIM pChildLayout AS CLayout = pChildDlg.hWindow
' // pChildLayout.AnchorControl(IDC_EDIT1, AFX_ANCHOR_WIDTH)
' // etc.
That's awesome code and a very usable feature for the class. Writing this editor has been so easy with the help of your class.
Well, it already has two users (you and me). I already have more than 80 small templates directly loadable from the editor. Examples that need to use resources will be offered separately.
I think that small templates can be very useful to beginners. They can be used as a starting point or as a source of code to copy. Many of them deal with specific issues. For example, today I have written a little one that demonstrates how to determine if the user has clicked the mouse in one of the status bar parts.
CASE WM_NOTIFY
' // Detect if the user has clicked the mouse in one of the status bar parts
DIM ptnmhdr AS NMHDR PTR
ptnmhdr = cast(NMHDR PTR, lParam)
SELECT CASE ptnmhdr->idFrom
CASE IDC_STATUSBAR
DIM lpnm AS NMMOUSE PTR
IF ptnmhdr->code = NM_CLICK THEN
lpnm = cast(NMMOUSE PTR, lParam)
' // Display the zero-based index of the section that was clicked.
MessageBoxW hwnd, "You have clicked section " & STR(lpnm->dwItemSpec), "", MB_OK
END IF
END SELECT
This was asked in the PB forum in 2009: https://forum.powerbasic.com/forum/user-to-user-discussions/powerbasic-for-windows/40783-determining-which-part-of-statusbar-was-clicked
It is useful to have a little example at hand because, often, you don't remember how can it be done and have to lose time researching it again.
I would like to write little examples dealing with frequently asked questions.
I had no luck with CWindow in the PowerBASIC forum, dominated by the DDTers, despite that this class is more powerful than DDT.
I want to convert my OLE container, mainly to host the WebBrowser control, because we can do amazing things with it and HTML5.