Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

Does anyone have the GetOpenFilename API code for opening custom dialog boxes (in particular with the ability to save the Views - Thumbnails, Tiles, Icons) in VB.Net, that actually works?

 

I've found code in C++ that I don't understand, in CE.Net that doesn't translate, I've found VB6 code and Access code that works but I have not been able to translate successfully yet. MSDN doesn't seem to have any examples in VB.Net, I've searched Google, this forum, and others. Occasionally I see someone who can't get multiple file selection or some aspect of it to work, but there's never any code along with it.

 

Please help! VB.Net!!!

 

Thanks,

Larry

Posted

I got the dialogbox to open...

 

But I keep getting a null reference when I try to use the OFNHookProc. Without the hook procedure, this is really no better than the standard OpenFileDialog box.

 

I'm using for the delegate:

Delegate Function OFNHookProc(ByVal hwnd As IntPtr, ByVal uMsg As Integer, ByVal wParam As Long, ByVal lParam As Long) As Integer

 

and setting the OpenFileName hook paramter to:

ofn.hook = New OFNHookProc(AddressOf OFNHookProcSub)

 

I've tried different variations of the parameter types such as Long, etc. In every case, when the OFNHookProcSub function fires, the handle and message being fed to it are meaningless - the message is none of the standard hook messages such as WM_NOTIFY (78) or WM_INITDIALOG (272). It's integer value is 48.

 

Again, I've seen hook examples in other languages, but nothing in VB.Net!

 

If anyone wants to see the code to get the dialogbox to just open, let me know!

 

Thanks,

Larry

Posted

Update - would you believe I'm "this" close?

 

Here's all the code for the entire class that I have so far (in 2 posts)...

 

Imports System

Imports System.Text

Imports Microsoft.VisualBasic

Imports System.Runtime.InteropServices

 

Public Class OpenFilename

Inherits CommonDialog

 

'Declare a bunch of API's, hoping some will work...

Declare Auto Function GetOpenFileName Lib "Comdlg32.dll" (<[in](), Out()> ByVal ofn As OpenFileName) As Boolean

Declare Function GetParent Lib "user32" (ByVal hwnd As IntPtr) As IntPtr

Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As String) As Long

Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As IntPtr) As Long

Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWndParent As IntPtr, ByVal hWndChildAfter As IntPtr, ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr

Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As IntPtr, ByVal lpString As String) As Long

Declare Auto Function SetDlgItemText Lib "user32" (ByVal hDlg As IntPtr, ByVal nIDDlgItem As Long, ByVal lpString As String) As Long

 

'Declare the Hook delegate so we can "hook" to it later.

Delegate Function OFNHookProc(ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr

'If you don't persist the hook procedure, it will be GC'd before the call gets to it.

Private HookProcSub As OFNHookProc = AddressOf HookProc

'Set the initial view - Thumbnail, Icons, Details, etc. (yeah, right!)

Private lngInitialView As Long

 

'Set all possible constants I've found so far.

''Hook constants

Const WM_SETFOCUS = &H7

Const WM_INITDIALOG = &H110

Const WM_LBUTTONDOWN = &H201

Const WM_RBUTTONDOWN = &H204

Const WM_MOVE = &H3

Const WM_COMMAND = &H111

Const WM_NOTIFY As Long = &H4E&

 

''Flags for OpenFileName

Const OFN_ALLOWMULTISELECT As Long = &H200

Const OFN_CREATEPROMPT As Long = &H2000

Const OFN_ENABLEHOOK As Long = &H20

Const OFN_ENABLETEMPLATE As Long = &H40

Const OFN_ENABLETEMPLATEHANDLE As Long = &H80

Const OFN_EXPLORER As Long = &H80000

Const OFN_EXTENSIONDIFFERENT As Long = &H400

Const OFN_FILEMUSTEXIST As Long = &H1000

Const OFN_HIDEREADONLY As Long = &H4

Const OFN_LONGNAMES As Long = &H200000

Const OFN_NOCHANGEDIR As Long = &H8

Const OFN_NODEREFERENCELINKS As Long = &H100000

Const OFN_NOLONGNAMES As Long = &H40000

Const OFN_NONETWORKBUTTON As Long = &H20000

Const OFN_NOREADONLYRETURN As Long = &H8000&

Const OFN_NOTESTFILECREATE As Long = &H10000

Const OFN_NOVALIDATE As Long = &H100

Const OFN_OVERWRITEPROMPT As Long = &H2

Const OFN_PATHMUSTEXIST As Long = &H800

Const OFN_READONLY As Long = &H1

Const OFN_SHAREAWARE As Long = &H4000

Const OFN_SHAREFALLTHROUGH As Long = 2

Const OFN_SHAREWARN As Long = 0

Const OFN_SHARENOWARN As Long = 1

Const OFN_SHOWHELP As Long = &H10

Const OFS_MAXPATHNAME As Long = 260

 

''ToolbarWindow32 buttons. I've actually only found the first two, and I'm guessing at the FileView button.

Const TB_BTN_UPONELEVEL = 40961

Const TB_BTN_NEWFOLDER = 40962

Const TB_BTN_FILEVIEW = 40963

Const BM_SETSTATE = &HF3

 

''Constants on the dialog window.

Const IDOK As Long = 1

Const IDCANCEL As Long = 2

Const IDFILEOFTYPETEXT As Long = &H441

Const IDFILENAMETEXT As Long = &H442

Const IDLOOKINTEXT As Long = &H443

Const WM_USER = &H400

Const CDM_FIRST = (WM_USER + 100)

Const CDM_SETCONTROLTEXT As Long = CDM_FIRST + &H4

Const CDM_HIDECONTROL As Long = (CDM_FIRST + &H5)

Const EM_GETTEXTRANGE = (WM_USER + 75)

Const TB_GETBUTTON = (WM_USER + 23)

 

''View constants.

Public Const SHVIEW_ICON As Long = &H7029

Public Const SHVIEW_LIST As Long = &H702B

Public Const SHVIEW_REPORT As Long = &H702C

Public Const SHVIEW_THUMBNAIL As Long = &H702D

Public Const SHVIEW_TILE As Long = &H702E

 

'Don't know what this is for, but it looked good

Public Structure TBBUTTON

Dim iBitmap As Integer

Dim idCommand As Integer

Dim fsState As Byte

Dim fsStyle As Byte

Dim bReserved1 As Byte

Dim bReserved2 As Byte

Dim dwData As Integer

Dim iString As Integer

End Structure

 

'Don't know what this is for, but it looked good

Public Structure LHDR

Public hwndFrom As IntPtr

Public idFrom As Integer

Public code As Integer

End Structure

 

'Don't know what this is for, but it looked good

Private Structure TEXTRANGE

Dim cpMin As Long

Dim cpMax As Long

Dim lpstrText As Long

End Structure

 

(rest of code to follow)

Posted

Update - continued

 

Public Property SetInitialView() As Long

Get

Return lngInitialView

End Get

Set(ByVal Value As Long)

lngInitialView = Value

End Set

End Property

 

'Hook procedure - uh huh...

<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _

Protected Overrides Function HookProc(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr

Dim hWndParent As IntPtr

Dim hwndLv As IntPtr

Dim hwndButton As IntPtr

Static bLvSetupDone As Boolean

Dim lngRetVal As Long

 

' Evaluates the message parameter to determine the user action.

 

Select Case msg

 

Case WM_INITDIALOG

bLvSetupDone = False

'MessageBox.Show("The WM_INITDIALOG message was received.")

Case WM_SETFOCUS

'MessageBox.Show("The WM_SETFOCUS message was received.")

Case WM_LBUTTONDOWN

'MessageBox.Show("The WM_LBUTTONDOWN message was received.")

Case WM_RBUTTONDOWN

'MessageBox.Show("The WM_RBUTTONDOWN message was received.")

Case WM_MOVE

'MessageBox.Show("The WM_MOVE message was received.")

Case WM_NOTIFY

If Not bLvSetupDone Then

'MessageBox.Show("The WM_NOTIFY message was received.")

hWndParent = GetParent(hWnd)

 

SetWindowText(hWndParent, "We're ALL bozos on this bus!")

'This actually works, so I know at least I'm pointing at the main dialog form.

 

hwndLv = FindWindowEx(hWndParent, hwndLv, "ToolbarWindow32", vbNullChar)

'This returns a handle, but not sure what to do with it. I don't know how to access the buttons in ToolbarWindow32.

 

Dim lhdr As LHDR = CType(Marshal.PtrToStructure(lParam, GetType(LHDR)), LHDR)

'This returns something, but not sure what to do with it.

lngRetVal = SendMessage(hwndLv, CDM_HIDECONTROL, TB_BTN_UPONELEVEL, 0)

'This certainly doesn't work - trying to hide the UpOneLevel button.

 

Dim strLookIn As String = "Find it in:" & ChrW(0)

lngRetVal = SendMessage(hWndParent, CDM_SETCONTROLTEXT, IDLOOKINTEXT, strLookIn)

'Attempt to change the text "Look In:" to "Find it in:" doesn't work.

bLvSetupDone = True

End If

End Select

 

' Always call the base class hook procedure.

Return MyBase.HookProc(hWnd, msg, wParam, lParam)

 

End Function

 

Public Overrides Sub Reset()

 

End Sub

 

'This is what's called from the front end button click -

' Dim OpenFile As New OpenFilename

' OpenFile.ShowDialog()

 

Protected Overrides Function RunDialog(ByVal hwndOwner As System.IntPtr) As Boolean

Dim ofn As New OpenFilename

 

With ofn

.nStructSize = Marshal.SizeOf(ofn)

.ptrOwner = hwndOwner

.sFilter = "Picture Files" & ChrW(0) & "*.jpg" & ChrW(0) & "All files" & ChrW(0) & "*.*" & ChrW(0)

.sFile = New String(New Char(256) {})

.nMaxFile = .sFile.Length

.sFileTitle = New String(New Char(64) {})

.nMaxFileTitle = .sFileTitle.Length

.sTitle = "Open file..."

.sDefExt = "jpg"

.nFlags = OFN_EXPLORER Or _

OFN_ENABLEHOOK Or _

OFN_LONGNAMES Or _

OFN_NODEREFERENCELINKS Or _

OFN_CREATEPROMPT Or _

OFN_ALLOWMULTISELECT

.ofnHook = HookProcSub

End With

 

If GetOpenFileName(ofn) Then

MessageBox.Show(ofn.sFile)

End If

 

End Function

 

'Even with persisting the hook, I still got a null reference unless I set up the OpenFileName like this:

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _

Public Class OpenFileName

Public nStructSize As Integer = 0

Public ptrOwner As IntPtr = IntPtr.Zero

Public hInstance As Integer = 0

<MarshalAs(UnmanagedType.LPTStr)> Public sFilter As String = Nothing

<MarshalAs(UnmanagedType.LPTStr)> Public sCustomFilter As String = Nothing

Public nMaxCustFilter As Integer = 0

Public nFilterIndex As Integer = 0

<MarshalAs(UnmanagedType.LPTStr)> Public sFile As String = Nothing

Public nMaxFile As Integer = 0

<MarshalAs(UnmanagedType.LPTStr)> Public sFileTitle As String = Nothing

Public nMaxFileTitle As Integer = 0

<MarshalAs(UnmanagedType.LPTStr)> Public sInitialDir As String = Nothing

<MarshalAs(UnmanagedType.LPTStr)> Public sTitle As String = Nothing

Public nFlags As Integer = 0

Public nFileOffset As Short = 0

Public nFileExt As Short = 0

Public sDefExt As String = Nothing

Public ptrCustData As IntPtr = IntPtr.Zero

Public ofnHook As OFNHookProc 'IntPtr = IntPtr.Zero

<MarshalAs(UnmanagedType.LPTStr)> Public sTemplateName As String = Nothing

Public ptrReserved As IntPtr = IntPtr.Zero

Public nReserved As Integer = 0

Public nFlagsEx As Integer = 0

End Class 'OpenFileName

 

End Class

Posted

Well, that does help a little...

 

Now at least I can "sorta" set the text in the buttons and main window, however, the text always looks like a little black square box with two white vertical lines in it. I tried null terminating the text strings. Maybe the text strings have to be put in a buffer or something.

 

I still can't access the buttons in the ToolbarWindow32.

 

Thanks so far PlausiblyDamp! And yes, almost everything I've found is non-VB.Net, so it's up for interpretation.

 

:)

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...