CWindow RC 17

Started by José Roca, August 15, 2016, 06:11:02 PM

Previous topic - Next topic

José Roca

CWindow Release Candidate 17

Incorporates the new GDI+ and ODBC classes.

The help file documents these classes and provides code snippets for most GDI+ methods.

José Roca

#1
In CWindow, add the following lines


   ' // Don't allow negative values for the styles
   IF dwStyle = -1 THEN dwStyle = 0
   IF dwExStyle = -1 THEN dwExStyle = 0


before


   ' // Make sure that the control has the WS_CHILD style
   dwStyle = dwStyle OR WS_CHILD
   ' // Create the control
   hCtl = .CreateWindowExW(dwExStyle, wsClassName, wszTitle, dwStyle, x * m_rx, y * m_ry, nWidth * m_rx, nHeight * m_ry, _
          hParent, CAST(HMENU, CAST(LONG_PTR, cID)), m_hInstance, CAST(LPVOID, lpParam))
   IF hCtl = NULL THEN EXIT FUNCTION


I changed the default value from 0 to -1 because Paul needed to pass 0 for a ownerdraw control and this causes CreatWindowExW to fail if these values remain as -1, for example when trying to create an instance of an user control.

José Roca

I have no idea, but looks useless. How is going another language to create instances of the classes and call its methods? This is not a binary standard like COM, but a proprietary system.

José Roca

I have implemented an OLE Container using classes and virtual methods. I have got it working, at least with the WebBrowser control, that is the one for which I have more interest. I will add some bells ans whistles, like support for licensed controls and register free activation of ActiveX controls.

I plan to write a WebBrowser wrapper class to take full advantage of this powerful control, that can be used for html, images, graphics, videos, and a lot of things more.

I also have plans for other classes such ADO and WinHTTP. We already have a powerful framework. When  Paul will finish his editor, we can launch the first official version.


Paul Squires

Wow, that's impressive! I didn't realize that you were going to work on the OLE container. Awesome.
I have 16 issues left to resolve before I upload the new editor source code. :)
Paul Squires
PlanetSquires Software

José Roca

#5
Got it!

For the WebBrowser control, we need to do:


DIM pOleCon AS COleCon PTR = NEW COleCon(@pWindow, 1001, "Shell.Explorer", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight - 20)
DIM pWb AS IWebBrowser2 PTR = cast(IWebBrowser2 PTR, pOleCon->OcxDispPtr)
DIM vUrl AS VARIANT
vUrl.vt = VT_BSTR
vUrl.bstrVal = SysAllocString("http://www.planetsquires.com/protect/forum/index.php")
DIM hr AS HRESULT = pWb->lpvtbl->Navigate2(pWb, @vUrl, NULL, NULL, NULL, NULL)
VariantClear @vurl


But I want to write a WebBrowser class to avoid the use of variants and, above all, to implement the IDocHostUIHandler interface, that allows to set a flag to make it DPI aware. Prevously, I used an optical zoom, that is deprecated.

Before James ask why I haven't declared the methods of the interfaces as private to avoid bloat, it is not possible because the functions aren't called by the FB code, but by the hosted ActiveX control, and FB has no way to know which ones will be called. If some are removed and the OCX calls them, it will crash.

José Roca

#6
I also have achieved to embed an old VB6 control, the MonthView Calendar, implemented in the licensed ActiveX MSCOMCT2.OCX, using a registration free technique that, unlike the one posted by a FB user, does not require the use of a manifest.


' ########################################################################################
' Microsoft Windows
' Contents: Embedded MonthView Calendar OCX
' Compiler: FreeBasic 32 & 64 bit
' Copyright (c) 2016 Jose Roca. Freeware. Use at your own risk.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#define UNICODE
'#define _OC_DEBUG_ 1
#INCLUDE ONCE "Afx/CWindow.inc"
#INCLUDE ONCE "Afx/COleCon/COleCon.inc"
USING Afx

DECLARE FUNCTION WinMain (BYVAL hInstance AS HINSTANCE, _
                          BYVAL hPrevInstance AS HINSTANCE, _
                          BYVAL szCmdLine AS ZSTRING PTR, _
                          BYVAL nCmdShow AS LONG) AS LONG

   END WinMain(GetModuleHandleW(NULL), NULL, COMMAND(), SW_NORMAL)

DECLARE FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS HINSTANCE, _
                  BYVAL hPrevInstance AS HINSTANCE, _
                  BYVAL szCmdLine AS ZSTRING PTR, _
                  BYVAL nCmdShow AS LONG) AS LONG

   CoInitialize NULL

   ' // Set process DPI aware
   ' // The recommended way is to use a manifest file
   AfxSetProcessDPIAware

   ' // Creates the main window
   DIM pWindow AS CWindow
   ' -or- DIM pWindow AS CWindow = "MyClassName" (use the name that you wish)
   pWindow.Create(NULL, "COleCon - Embedded MonthView Calendar OCX", @WndProc)
   ' // Sizes it by setting the wanted width and height of its client area
   pWindow.SetClientSize(580, 360)
   ' // Centers the window
   pWindow.Center

   DIM wszLibName AS WSTRING * 260 = ExePath & "\MSCOMCT2.OCX"
   DIM CLSID_MSComCtl2_MonthView AS CLSID = (&h232E456A, &h87C3, &h11D1, {&h8B, &hE3,&h00, &h00, &hF8, &h75, &h4D, &hA1})
   DIM IID_MSComCtl2_MonthView AS CLSID = (&h232E4565, &h87C3, &h11D1, {&h8B, &hE3,&h00, &h00, &hF8, &h75, &h4D, &hA1})
   DIM RTLKEY_MSCOMCT2 AS WSTRING * 260 = "651A8940-87C5-11d1-8BE3-0000F8754DA1"
   DIM pOleCon AS COleCon PTR = NEW COleCon(@pWindow, 1001, wszLibName, CLSID_MSComCtl2_MonthView, _
       IID_MSComCtl2_MonthView, RTLKEY_MSCOMCT2, 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)

   ' // Displays the window and dispatches the Windows messages
   FUNCTION = pWindow.DoEvents(nCmdShow)

   IF pOleCon THEN Delete pOleCon
   CoUnInitialize

END FUNCTION
' ========================================================================================

' ========================================================================================
' Main window procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

   SELECT CASE uMsg

      CASE WM_CREATE
         ' // If you want to create controls in WM_CREATE instead of in WinMain, you can
         ' // retrieve a pointer of the class with AfxCWindowPtr(lParam). Use hwnd as the
         ' // handle of the window instead of pWindow->hWindow or omitting this parameter
         ' // because CWindow doesn't know the value of this handle until the WM_CREATE
         ' // message has been processed.
         ' DIM pWindow AS CWindow PTR = AfxCWindowPtr(lParam)
         ' IF pWindow THEN pWindow->AddControl("Button", hwnd, IDCANCEL, "&Close", 350, 250, 75, 23)
         ' // An alternative is no pass the value of the main window handle to CWindow with
         ' DIM pWindow AS CWindow PTR = AfxCWindowPtr(lParam)
         ' pWindow->hWindow = hwnd
         ' IF pWindow THEN pWindow->AddControl("Button", , IDCANCEL, "&Close", 350, 250, 75, 23)
         EXIT FUNCTION

      CASE WM_COMMAND
         SELECT CASE LOWORD(wParam)
            CASE IDCANCEL
               ' // If ESC key pressed, close the application by sending an WM_CLOSE message
               IF HIWORD(wParam) = BN_CLICKED THEN
                  SendMessageW hwnd, WM_CLOSE, 0, 0
                  EXIT FUNCTION
               END IF
         END SELECT

      CASE WM_SIZE
         ' // Optional resizing code
         IF wParam <> SIZE_MINIMIZED THEN
            ' // Retrieve a pointer to the CWindow class
            DIM pWindow AS CWindow PTR = AfxCWindowPtr(hwnd)
            ' // Move the position of the button
            IF pWindow THEN pWindow->MoveWindow GetDlgItem(hwnd, 1001), _
               0, 0, pWindow->ClientWidth, pWindow->ClientHeight, CTRUE
         END IF

    CASE WM_DESTROY
         ' // Ends the application by sending a WM_QUIT message
         PostQuitMessage(0)
         EXIT FUNCTION

   END SELECT

   ' // Default processing of Windows messages
   FUNCTION = DefWindowProcW(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================


Funny that they have localized the names of the months, but not "Today".

Paul Squires

Quote from: John Spikowski on August 19, 2016, 02:59:28 AM
QuoteWhen Paul will finish his editor, we can launch the first official version.

Will this be a fork of the original FreeBASIC project?
It is in addition to the current WinFBE that already exists in GitHub. That version has a classic kind of editor interface whereas the one I am working on now uses a more modern and clean interface. Both do the same thing: edit and compile code.

Quote
Will FireFly ever be made open source?
No, I already answered this exact same question for you. http://www.planetsquires.com/protect/forum/index.php?topic=3496.msg29128#msg29128

Once the editor project is completed, I would like to get back at the grid control project. That is a key control that a lot of projects need. In combination with Jose's classes, the FB tool chain will be quite strong at that point.
Paul Squires
PlanetSquires Software

José Roca

This is a personal project in which nobody else is collaborating. I always use "Freeware" in all the code that I publish, and never "Open Source".

"Freeware is proprietary software that is available for use at no monetary cost. In other words, freeware may be used without payment but may usually not be modified, re-distributed or reverse-engineered without the author's permission."

Just because the source code is avilable doesn't mean that the followers of the Open Source movement can seize it.

James Fuller

Jose,
  How about COM a demo we can try?
Maybe Fred's Grid control?

James

James Fuller

Jose,
  Even though I don't do 32bit any more, I found the 32bit ocx and it worked fine with Fb32.

James


José Roca

It would require to prepare headers first and all that.

BTW to make it easier to use I have added the following changes:

Initialize the COM library when the constructors are called.


' // Initialize the COM library
DIM hr AS HRESULT = OleInitialize(NULL)
IF hr = S_OK OR hr = S_FALSE THEN m_bUninitOLE = TRUE


Uninitialize it when the class is destroyed.


IF m_bUninitOLE THEN OleUninitialize


Multiple calls to CoInitialize or OleInitialize are allowed as long as each call to the initialize function is paired with a call to the uninitialize function.

I'm using OleInitialize instead of CoInitialize because OleInitialize adds the following functionality:

- Clipboard
- Drag and Drop
- Object linking and embedding (OLE)
- In-place activation

OleInitialize specifies the concurrency model as single-thread apartment (STA).

José Roca

Quote from: James Fuller on August 19, 2016, 02:37:51 PM
Jose,
  Even though I don't do 32bit any more, I found the 32bit ocx and it worked fine with Fb32.

James

I have chosen it because it could try it without having to prepare headers first. I don't want to try the other VB6 controls because they're 32-bit only and it is too much work to prepare the headers.

José Roca

With the changes, instead of


   DIM wszLibName AS WSTRING * 260 = ExePath & "\MSCOMCT2.OCX"
   DIM CLSID_MSComCtl2_MonthView AS CLSID = (&h232E456A, &h87C3, &h11D1, {&h8B, &hE3,&h00, &h00, &hF8, &h75, &h4D, &hA1})
   DIM IID_MSComCtl2_MonthView AS CLSID = (&h232E4565, &h87C3, &h11D1, {&h8B, &hE3,&h00, &h00, &hF8, &h75, &h4D, &hA1})
   DIM RTLKEY_MSCOMCT2 AS WSTRING * 260 = "651A8940-87C5-11d1-8BE3-0000F8754DA1"
   DIM pOleCon AS COleCon PTR = NEW COleCon(@pWindow, 1001, wszLibName, CLSID_MSComCtl2_MonthView, _
       IID_MSComCtl2_MonthView, RTLKEY_MSCOMCT2)
   DIM pOleCon2 AS COleCon PTR = NEW COleCon(@pWindow, 1002, wszLibName, CLSID_MSComCtl2_MonthView, _
       IID_MSComCtl2_MonthView, RTLKEY_MSCOMCT2)

   ' // Displays the window and dispatches the Windows messages
   FUNCTION = pWindow.DoEvents(nCmdShow)

   IF pOleCon THEN Delete pOleCon
   IF pOleCon2 THEN Delete pOleCon2
   CoUnInitialize


we can use


   DIM wszLibName AS WSTRING * 260 = ExePath & "\MSCOMCT2.OCX"
   DIM CLSID_MSComCtl2_MonthView AS CLSID = (&h232E456A, &h87C3, &h11D1, {&h8B, &hE3,&h00, &h00, &hF8, &h75, &h4D, &hA1})
   DIM IID_MSComCtl2_MonthView AS CLSID = (&h232E4565, &h87C3, &h11D1, {&h8B, &hE3,&h00, &h00, &hF8, &h75, &h4D, &hA1})
   DIM RTLKEY_MSCOMCT2 AS WSTRING * 260 = "651A8940-87C5-11d1-8BE3-0000F8754DA1"
   DIM pOleCon AS COleCon = COleCon(@pWindow, 1001, wszLibName, CLSID_MSComCtl2_MonthView, _
       IID_MSComCtl2_MonthView, RTLKEY_MSCOMCT2)
   DIM pOleCon2 AS COleCon = COleCon(@pWindow, 1002, wszLibName, CLSID_MSComCtl2_MonthView, _
       IID_MSComCtl2_MonthView, RTLKEY_MSCOMCT2)

   ' // Displays the window and dispatches the Windows messages
   FUNCTION = pWindow.DoEvents(nCmdShow)


José Roca

#14
> I tried the embedded calendar control example and all I get is the base window with the title and the client area blank. I didn't get any errors with the compile. The MSCOMCT2.OCX is resident on my Windows 7 32 bit OS.

If the OCX is registered, you only need to pass the ProgID. The example that I have posted is for embedding unregistered OCXs.

> Does this mean we are not permitted to fix bugs or enhance the libraries?

If you make changes, keep them private. If you still don't know what Freeware means, please do a Google search. It is almost the opposite to Open Source.

> Here is a C# .NET date picker compiled as a COM control

Mine is embedded in the application and yours not. The purpose of an OLE Container is to embed the control, not to launch another application that hosts it.