First COM attempt: IFileOpenDialog

Started by José Roca, April 06, 2016, 02:13:57 PM

Previous topic - Next topic

José Roca


' ########################################################################################
' Microsoft Windows
' File: CW_IFileOpenDialog.fbtpl - Template
' Contents: Demonstrates the use of the IFileOpenDialog interface.
' 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 _WIN32_WINNT &h0602
#INCLUDE ONCE "windows.bi"
#INCLUDE ONCE "win/shobjidl.bi"
#INCLUDE ONCE "Afx/CWindow.inc"

USING Afx.CWindowClass

CONST IDC_OFD = 1001

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, COMMAND(), SW_NORMAL)

' ========================================================================================
' Displays the FileOpenDialog.
' The returned pointer must be freed with CoTaskMemFree
' ========================================================================================
FUNCTION AfxIFileOpenDialogW (BYVAL hwndOwner AS HWND) AS WSTRING PTR

   DIM hr AS LONG
   DIM CLSID_FileOpenDialog AS CLSID = (&hDC1C5A9C, &hE88A, &h4DDE, {&hA5, &hA1, &h60, &hF8, &h2A, &h20, &hAE, &hF7})
   DIM IID_IFileOpenDialog AS GUID   = (&hD57C7288, &hD4AD, &h4768, {&hBE, &h02, &h9D, &h96, &h95, &h32, &hD9, &h60})

   ' // Create an instance of the FileOpenDialog object
   DIM pofd AS IFileOpenDialog PTR
   hr = CoCreateInstance(@CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, @IID_IFileOpenDialog, @pofd)
   IF pofd = NULL THEN RETURN NULL

   ' // Set the file types
   DIM rgFileTypes(1 TO 3) AS COMDLG_FILTERSPEC
   rgFileTypes(1).pszName = @WSTR("PB code files")
   rgFileTypes(2).pszName = @WSTR("Executable files")
   rgFileTypes(3).pszName = @WSTR("All files")
   rgFileTypes(1).pszSpec = @WSTR("*.bas;*.inc")
   rgFileTypes(2).pszSpec = @WSTR("*.exe;*.dll")
   rgFileTypes(3).pszSpec = @WSTR("*.*")
   pofd->lpVtbl->SetFileTypes(pofd, 3, @rgFileTypes(1))

   ' // Set the title of the dialog
   hr = pofd->lpVtbl->SetTitle(pofd, "A Single-Selection Dialog")
   ' // Display the dialog
   hr = pofd->lpVtbl->Show(pofd, hwndOwner)

   ' // Get the result
   DIM pItem AS IShellItem PTR
   DIM pwszName AS WSTRING PTR
   IF SUCCEEDED(hr) THEN
      hr = pofd->lpVtbl->GetResult(pofd, @pItem)
      IF SUCCEEDED(hr) THEN
         hr = pItem->lpVtbl->GetDisplayName(pItem, SIGDN_FILESYSPATH, @pwszName)
         FUNCTION = pwszName
      END IF
   END IF

   ' // Cleanup
   IF pItem THEN pItem->lpVtbl->Release(pItem)
   IF pofd THEN pofd->lpVtbl->Release(pofd)

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

' ========================================================================================
' 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
         EXIT FUNCTION

      CASE WM_COMMAND
         SELECT CASE LOWORD(wParam)
            CASE IDCANCEL
               IF HIWORD(wParam) = BN_CLICKED THEN
                  SendMessageW hwnd, WM_CLOSE, 0, 0
                  EXIT FUNCTION
               END IF
            CASE IDC_OFD
               IF HIWORD(wParam) = BN_CLICKED THEN
                  ' // Display the Open File Dialog
                  DIM pwszName AS WSTRING PTR = AfxIFileOpenDialogW(hwnd)
                  ' // Display the name of the selected file
                  IF pwszName THEN
                     MessageBoxW(hwnd, *pwszName, "IFileOpenDialog", MB_OK)
                     CoTaskMemFree pwszName
                  END IF
                  EXIT FUNCTION
               END IF
         END SELECT

    CASE WM_DESTROY
         PostQuitMessage(0)
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProcW(hWnd, uMsg, wParam, lParam)

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

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

   ' // Initialize the COM library
   CoInitialize(NULL)

   ' // Set process DPI aware
   AfxSetProcessDPIAware

   DIM pWindow AS CWindow
   pWindow.Create(NULL, "IFileOpenDialog example", @WndProc)
   pWindow.SetClientSize(500, 320)
   pWindow.Center

   ' // Add a button
   pWindow.AddControl("Button", pWindow.hWindow, IDC_OFD, "&Open File Dialog", 350, 250, 110, 23)

   

   ' // Process event messages
   FUNCTION = pWindow.DoEvents(nCmdShow)

   ' // Uninitialize the COM library
   CoUninitialize

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


Paul Squires

Paul Squires
PlanetSquires Software

José Roca

#2
It is like coming back to the times of PowerBASIC 6.1.

Fortunately I did learn COM programming the hard way and know how to work with it at low level.

Dominic will be happy with this compiler, because he likes to program this way.

aloberr

good work josé
I tried to convert your OLECON;inc to Freebasic and for now this work for some activex  and fails for another.
perhaps it is not good to post it for the moment?

José Roca

Post it here if you want and I will look at it.

aloberr


José Roca

Too big to post the source code, but have you tried to zip it as post it as an attachment?

Can't connect with

http://www.2shared.com/file/_SRYrFCZ/OLECON.html

at this moment. It time-outs.

José Roca

I finally have been able to download it.

aloberr

#8
Sorry , one thing is that you need some modified headers.
here the grinding of FREEBASIC 1.05.0 containing the .bi files modified to also take into account the virtual classes
It is necessary to remind that these are only the files contained in the Win folder which are concerned. 
The remainder without chagement. 

A possibility is to rename the folder Freebasic/inc/win in your installation by Freebasic/inc/win_ and to copy my folder win in Freebasic/inc/

test your old projects, they will have to work. 
if you have a project using the vtbl, it will be necessary to add in any beginning  #define _ FB_COM_VTBL _
http://www.2shared.com/file/11E5di-_/win.html
some examples to test: http://www.2shared.com/file/eJYl-WIo/test_project.html

José Roca

> and for now this work for some activex and fails for another.

Can you tell me which ones work and which ones fail?

Be aware that some VB OCXs never have worked fine with my OLE container.

For example, the FlexGrid and the MSHFlexGrid worked, but the DataGrid one don't.

aloberr

yes Jose, but there is still work to make with the FREEBASIC version
here is an example of use of msflxgrid
testolecon_reg.exe has a bug while clicking on the header of the grid
whereas testolecon_notreg.exe functions correctly
http://www.2shared.com/file/sG_EmGhc/msflexgrid_test.html

James Fuller

Jose,
  What is your position of COM with FreeBasic?
#1- I am working on my own approach.
#2- I am trying to adapt and use some/all of aloberr's code.
#3- Not interested.

James


José Roca

I think that I'm going to use low-lewel COM and some helper functions. After all, now that the old VB OCXs are obsolete, we almost only need Automation to work with Office, and I don't use it.

Everything else that I have tried is not fully satisfactory. There is always the problem of freeing the temporary variables.

James Fuller

Jose,
  I just noticed this example is for Win8+.
I thought you were running Win7?
Is it possible to target Win7 +

James

José Roca

What makes you think that it is for Windows 8? I'm using Windows 7.