PlanetSquires Forums

Support Forums => PlanetSquires Software => Topic started by: Paul Squires on June 06, 2016, 08:11:45 PM

Title: WinFBE using CWindow #4
Post by: Paul Squires on June 06, 2016, 08:11:45 PM
Attached is the latest source code. I have been working on the "Environment Options" dialogs. The options are also saved and restored from a configuration file.

Updated: June 7, 2016
Updated: June 7, 2016 (later that evening)
Title: Re: WinFBE using CWindow #4
Post by: José Roca on June 06, 2016, 08:39:18 PM
Remove the deletion of CWindow from the WM_DESTROY message and put it after DoEvents:


Function frmOptions_Show( ByVal hWndParent As HWnd, _
                          ByVal nCmdShow   As Long = 0 _
                          ) As Long

...
...


   ' Process Windows messages
   Function = pWindow->DoEvents(nCmdShow)

   ' // Destroy the CWindow class
   Delete pWindow


Otherwise, DoEvents is going to call a method that doesn't exist anymore.
Title: Re: WinFBE using CWindow #4
Post by: José Roca on June 06, 2016, 08:47:43 PM
Remember that after receiving the WM_DESTROY message, the message pump must still exist to process the PostQuitMessage. If you delete the class, the pWindow pointer of pWindow.DoEvents is no longer valid.
Title: Re: WinFBE using CWindow #4
Post by: Paul Squires on June 06, 2016, 10:03:32 PM
Thanks Jose! I have now made those changes. :)

The gpf is in my version of the color selection combobox. I see mistakes where I forgot to change code when going from ANSI to the UNICODE version.  I should have it all fixed by tomorrow.
Title: Re: WinFBE using CWindow #4
Post by: Paul Squires on June 07, 2016, 04:17:00 PM
Updated the first post with the latest code.
Fixed gpfs on 64 bit.
Now using Jose's COM implementation of the FileOpenDialog (AfxIFileOpenDialogW).
Title: Re: WinFBE using CWindow #4
Post by: James Fuller on June 07, 2016, 05:29:28 PM
Paul,
  Looks good but no menu items working except Exit and Environment the latter is still a bit goofy.
Sometimes it gpf's other times not. Setting paths and or the help path can trigger a gpf.
Sometimes the popup  just shows the headings.
James
Win10 and fb64
Title: Re: WinFBE using CWindow #4
Post by: Paul Squires on June 07, 2016, 06:02:36 PM
Hmmm... I am wondering if the gpfs are related to using Jose's new COM version of the FileOpenDialog? I hope that I am using it correctly. I need to track down 100% of why the gpfs occur. It seems to happen on 64 bit more often.

I haven't moved the code for the other menu items there yet because I wanted to nail down the core of the environment options first. The techniques I learn there will help me using the CWindow class throughout the rest of the editor. I have huge chunks of code ready to put into the editor because I had already a large portion of the editor using FireFly. Lots of code is based on Jose's code from his SED Editor.
Title: Re: WinFBE using CWindow #4
Post by: Paul Squires on June 07, 2016, 06:03:42 PM
Quote from: James Fuller on June 07, 2016, 05:29:28 PM
Sometimes the popup  just shows the headings.

That's interesting. I have never seen that happen in all my tests.
Title: Re: WinFBE using CWindow #4
Post by: James Fuller on June 07, 2016, 07:42:56 PM
Quote from: TechSupport on June 07, 2016, 06:03:42 PM
Quote from: James Fuller on June 07, 2016, 05:29:28 PM
Sometimes the popup  just shows the headings.

That's interesting. I have never seen that happen in all my tests.

Here are the screen shots.
James

Title: Re: WinFBE using CWindow #4
Post by: Paul Squires on June 07, 2016, 08:49:12 PM
Thanks James! Not sure why that would happen. If it happens again then maybe you can run Spy.exe and examine the main options window to see if the 3 child windows exist. Tey should be named FBWindowClass:2, FBWindowClass:3, and FBWindowClass:4. Maybe they are created but now being shown correctly by my code.

My code calls:
TreeView_SelectItem( hWndTreeview, hItem)

and that should trigger the TVN_SELCHANGED notification. The code that responds to that notification hides/shows the correct child window and moves it into place.
Title: Re: WinFBE using CWindow #4
Post by: Paul Squires on June 07, 2016, 08:52:48 PM
I have updated the initial post with new source code. I moved the DELETE pWindow code out of the WM_DESTROY for each of the 3 child sub-forms of the Options Dialog. I moved it a place after the main Options dialog is destroyed. I recompiled and ran the program several times and have not seen a GPF. I have also changed some code that I think was wrong related to using the function SetWindowTextW.

Please let me know if you continue to see any GPFs.

Thanks!
Title: Re: WinFBE using CWindow #4
Post by: José Roca on June 07, 2016, 09:54:15 PM
Hi Paul,

One thing that you have to change is pWindow->GetControlWindowRect( hLabel, @rc ) to GetWindowRect( hLabel, @rc ).


             ' Move the child Form into place. The child form will be displayed under the header label.
             Dim rc As Rect
'             pWindow->GetControlWindowRect( hLabel, @rc )
             GetWindowRect( hLabel, @rc )
             MapWindowPoints( Null, HWnd, Cast(LPPOINT, @rc), 2 )
             SetWindowPos hForm, HWND_TOP, _
                            rc.Left + pWindow->ScaleX(5), pWindow->ScaleY(50), _
                            pWindow->ScaleX(370), pWindow->ScaleY(300), _
                            SWP_SHOWWINDOW

             InvalidateRect HWnd, ByVal Null, True
             UpdateWindow HWnd


The CWindow Rect functions, and also others, return unscaled values suitable to be used when they are going to be passed to another CWindow function that will scale them. But as MapWindowPoints s an API function, we have to pass the scaled values (as the windows and controls are already scaled, GetWindowRect will return the correct values).
Title: Re: WinFBE using CWindow #4
Post by: José Roca on June 07, 2016, 10:10:35 PM
Another way to do it:


             Dim rc As Rect
             GetWindowRect( hLabel, @rc )
             MapWindowPoints( Null, HWnd, Cast(LPPOINT, @rc), 2 )
             ' // Unscale rc.Left because SetWindowPos will scale the values
             rc.Left   /= pWindow->rxRatio
             pWindow->SetWindowPos hForm, HWND_TOP, _
                            rc.Left + 5, 50, _
                            370, 300, _
                            SWP_SHOWWINDOW

Title: Re: WinFBE using CWindow #4
Post by: José Roca on June 07, 2016, 10:16:02 PM
That is, CWindow methods such CWindow.GetWindowRect, CWindow.GetClientRect, CWindow.GetControlWindowRect, CWindow.ControlWidth or CWindow.ControlHeight, return unscaled values suitable to be passed to another CWindow method.

But if the target is an API function, then use the API counterparts, such GetWindowRect or GetClientRect. Otherwise, you will be passing unscaled values to functions that don't scale them.

Clear as mud :)
Title: Re: WinFBE using CWindow #4
Post by: José Roca on June 07, 2016, 10:19:51 PM
After my change, it looks correct in my computer, at 192 DPI. See the capture.
Title: Re: WinFBE using CWindow #4
Post by: José Roca on June 07, 2016, 10:27:56 PM
In the CTabPage class of CWindow, the method that creates the tab page unscales the values because the Create method will scale them.


   .GetWindowRect(hTab, @rc)
   .SendMessageW hTab, TCM_ADJUSTRECT, FALSE, CAST(lParam, @rc)
   .MapWindowPoints NULL, hTab, CAST(LPPOINT, @rc), 2
   ' // Adjust for High DPI because create will resize the values
   rc.Left   /= this.rxRatio
   rc.Right  /= this.rxRatio
   rc.Top    /= this.ryRatio
   rc.Bottom /= this.ryRatio
   ' // Calculate coordinates and size
   x = rc.Left
   y = rc.Top
   nWidth  = max(1, rc.Right - rc.Left)
   nHeight = max(1, rc.Bottom - rc.Top)
   m_hTabPage = this.Create(hTab, wszTitle, lpfnWndProc, x, y, nWidth, nHeight, dwStyle, dwExStyle)


but in the method that resizes the pages I don't unscale anything because I'm just caling API functions.


            DIM rcParent AS RECT
            .GetWindowRect(hTab, @rcParent)
            ' // Calculates the tab control's display area given its window rectangle
            .SendMessageW(hTab, TCM_ADJUSTRECT, FALSE, CAST(LPARAM, @rcParent))
            ' // Convert to window coordinates
            .MapWindowPoints(NULL, hTab, CAST(LPPOINT, @rcParent), 2)
            ' // Move the tab page
            .MoveWindow(pTabPage->hTabPage, rcParent.Left, rcParent.Top, _
               rcParent.Right - rcParent.Left, rcParent.Bottom - rcParent.Top, CTRUE)

Title: Re: WinFBE using CWindow #4
Post by: Paul Squires on June 07, 2016, 10:49:46 PM
Yup, clear as mud  :)

I have made the changes and I'll try to remember this as I continue coding the application. :)
Title: Re: WinFBE using CWindow #4
Post by: José Roca on June 07, 2016, 11:02:27 PM
Another suggested change:

In modCBColor.inc, change


SelectFont( lpdis->hDC, GetStockObject(DEFAULT_GUI_FONT) )


to


SelectFont( lpdis->hDC, AfxCWindowPtr(hwnd)->Font)


With GetStockObject(DEFAULT_GUI_FONT) the font appears smaller than it should in my system.

With SelectFont( lpdis->hDC, AfxCWindowPtr(hwnd)->Font) it will use the same scaled font that the main window.

Notice the convenience of AfxCWindowPtr(hwnd), a clever function that not only allows you to retrieve the CWindow pointer passing the handle of the main window or the handle of any of its child controls, but also lets you to call the methods of CWindow directly, using the -> notation, without having to do:


DIM pWindow AS CWindow PTR
pWindow = AfxCWindowPtr(hwnd)
pWindow->Font


BTW I'm working in wrappers for the common controls.
Title: Re: WinFBE using CWindow #4
Post by: Paul Squires on June 07, 2016, 11:05:28 PM
AfxCWindowPtr(hwnd)->Font

That syntax is very clever!

Yes, i am making the change right now.  :)
Title: Re: WinFBE using CWindow #4
Post by: Paul Squires on June 07, 2016, 11:17:22 PM
Quote from: Jose Roca on June 07, 2016, 11:02:27 PM

BTW I'm working in wrappers for the common controls.


Definitely looking forward to these wrappers!

My next step now is to revisit the class structure that I set up for document handling. I want the editor to be able to handle multiple projects at once.

Workspace
-- Project 1
---- File 1
---- File 2
---- File 3
---- etc
-- Project 2
-- etc

Each project will need to be able to specify compiler options. Likewise, each file within a project needs to be able to have compiler options specified (because some files may be compiled into OBJ and then linked to the main BAS).

Also, need to think about how to handle the build process so that only dirty files are recompiled (unless Rebuild All is specified).

Just starting to think about this stuff but it is important to get it right because the entire guts of the editor will then revolve around it.
Title: Re: WinFBE using CWindow #4
Post by: José Roca on June 08, 2016, 12:12:14 AM
Quote from: TechSupport on June 07, 2016, 11:05:28 PM
AfxCWindowPtr(hwnd)->Font

That syntax is very clever!

Yes, i am making the change right now.  :)


That's a technique that I suggested to the late Bob Zale to improve the PB COM support and that I called calculated object reference. FB classes are not COM classes, but the principle is the same, only the way to achieve it differs. Fortunetely, some clever guys did a good job implementing function pointers in FB, so it has been easy.

I tried hard to modernize PB programming, but apparently my techniques are above most PBer's heads. DDT has triumphed and it wil turn against them.