Solved

Windows API ChooseFont EnableHook FindResFailure

Posted on 2008-06-18
7
277 Views
Last Modified: 2010-04-23
I'm trying to implement the API ChooseFont function. I've got everything working fine except when I try and implement the EnableHook. When I do, I get the error FindResFailure returned from CommDlgExtendedError(). Any idea as to what Resource wasn't found and how I can get this to work?
Public Delegate Function CFHookProcDelegate(ByVal hdlg As Integer, ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer  
 
Private Function HookProc(ByVal hWnd As Integer, ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
 
    Select Case (msg)
        Case API.WindowMessage.InitDialog
            ' Center the dialog based on the user's preference
            m_hWndParent = API.GetParent(hWnd)
            Select Case StartPosition
                Case FormStartPosition.CenterParent
                    CenterParentWindow(hWnd)
                Case FormStartPosition.CenterScreen
                    CenterScreenWindow(hWnd)
            End Select
    End Select
    Return 0
End Function
 
Public Function ShowDialog() As DialogResult   
    PopulateCFStructure   
  
    ' Show the dialog   
    If Not API.CHOOSEFONT(m_cf) Then  
        Dim ret As Integer = API.CommDlgExtendedError()   
  
        Select Case ret   
            Case 0   
            Case API.CommonDialogError.DialogFailure   
                Throw New ApplicationException(("Couldn't show Dialog - Dialog Failure (" +    
ret.ToString + ")"))   
            Case API.CommonDialogError.FindResFailure   
                Throw New ApplicationException(("Couldn't show Dialog - Find Resource Failure (" + ret.ToString + ")"))   
            Case API.CommonDialogError.GeneralCodes   
                Throw New ApplicationException(("Couldn't show Dialog - General Codes Failure (" + ret.ToString + ")"))   
            Case API.CommonDialogError.Initialization   
                Throw New ApplicationException(("Couldn't show Dialog - Initialization Failure (" + ret.ToString + ")"))   
            Case API.CommonDialogError.LoadResFailure   
                Throw New ApplicationException(("Couldn't show Dialog - Load Resource Failure (" + ret.ToString + ")"))   
            Case API.CommonDialogError.LoadStrFailure   
                Throw New ApplicationException(("Couldn't show Dialog - Load String Failure (" + ret.ToString + ")"))   
            Case API.CommonDialogError.LockResFailure   
                Throw New ApplicationException(("Couldn't show Dialog - Lock Resource Failure (" + ret.ToString + ")"))   
            Case API.CommonDialogError.MemAllocFailure   
                Throw New ApplicationException(("Couldn't show Dialog - Memory Allocation Failure (" + ret.ToString + ")"))   
            Case API.CommonDialogError.MemLockFailure   
                Throw New ApplicationException(("Couldn't show Dialog - Memory Lock Failure (" + ret.ToString + ")"))   
            Case API.CommonDialogError.NoHInstance   
                Throw New ApplicationException(("Couldn't show Dialog - No HInstance Failure (" + ret.ToString + ")"))   
            Case API.CommonDialogError.NoHook   
                Throw New ApplicationException(("Couldn't show Dialog - No Hook Failure (" + ret.ToString + ")"))   
            Case API.CommonDialogError.RegisterMsgFail   
                Throw New ApplicationException(("Couldn't show Dialog - Register Message Failure (" + ret.ToString + ")"))   
            Case API.CommonDialogError.NoTemplate   
                Throw New ApplicationException(("Couldn't show Dialog - No Template Failure (" + ret.ToString + ")"))   
            Case API.CommonDialogError.StructSize   
                Throw New ApplicationException(("Couldn't show Dialog - Structure Size Failure (" + ret.ToString + ")"))   
            Case Else  
                Throw New ApplicationException(("Couldn't show Dialog - (" + ret.ToString +    
")"))   
        End Select  
        m_Color = Nothing  
        Return DialogResult.Cancel   
    Else  
        Dim cancelCheck As New CancelEventArgs()   
  
        RaiseEvent FileOK(Me, cancelCheck)   
        If cancelCheck.Cancel Then  
            m_Color = Nothing  
            Return DialogResult.Cancel   
        Else  
            Dim iFontStyle As Integer  
            Dim R As Integer = m_cf.rgbColors And &HFF   
            Dim G As Integer = (m_cf.rgbColors >> 8) And &HFF   
            Dim B As Integer = (m_cf.rgbColors >> 16) And &HFF   
            Dim retLogFont As API.LOGFONT = CType(Marshal.PtrToStructure(New    
IntPtr(m_cf.lpLogFont), GetType(API.LOGFONT)), API.LOGFONT)   
        
            Me.Color = Color.FromArgb(R, G, B)   
            iFontStyle = FontStyle.Regular   
            If m_cf.nFontType And API.FontType.Bold Then  
                iFontStyle = iFontStyle Or FontStyle.Bold   
            End If  
            If m_cf.nFontType And API.FontType.Italic Then  
                iFontStyle = iFontStyle Or FontStyle.Italic   
            End If  
            If retLogFont.lfStrikeOut Then  
                iFontStyle = iFontStyle Or FontStyle.Strikeout   
            End If  
            If retLogFont.lfUnderline Then  
                iFontStyle = iFontStyle Or FontStyle.Underline   
            End If  
  
            Me.Font = New Font(retLogFont.lfFaceName, -retLogFont.lfHeight, iFontStyle,    
GraphicsUnit.Pixel)   
  
            Return DialogResult.OK   
        End If  
    End If  
End Function  
  
Private Function GetFlags() As Integer  
    Dim Flags As Integer  
  
    Flags = API.ChooseColorFlags.EnableHook Or API.ChooseFontFlags.InitToLogFontStruct Or API.ChooseFontFlags.Both Or API.ChooseFontFlags.Effects   
    If m_ShowHelp Then Flags = Flags Or API.ChooseColorFlags.ShowHelp   
  
    Return Flags   
End Function  
  
Private Function PopulateCFStructure() As Boolean  
  
    Try  
        ' lfHeight is in Pixels. Convert Font.SizeInPoints to Pixels   
        m_LogFont.lfHeight = -PointToPixels(m_Font.SizeInPoints)   
        If m_Font.Bold Then  
            m_LogFont.lfWeight = API.FontWeight.FW_BOLD   
        Else  
            m_LogFont.lfWeight = API.FontWeight.FW_NORMAL   
        End If  
        If m_Font.Italic Then  
            m_LogFont.lfItalic = 1   
        Else  
            m_LogFont.lfItalic = 0   
        End If  
        If m_Font.Underline Then  
            m_LogFont.lfUnderline = 1   
        Else  
            m_LogFont.lfUnderline = 0   
        End If  
        If m_Font.Strikeout Then  
            m_LogFont.lfStrikeOut = 1   
        Else  
            m_LogFont.lfStrikeOut = 0   
        End If  
        m_LogFont.lfFaceName = m_Font.Name   
        m_LogFont.lfCharSet = API.FontCharSet.DEFAULT_CHARSET   
        m_LogFont.lfOutPrecision = API.FontPrecision.OUT_DEFAULT_PRECIS   
        m_LogFont.lfClipPrecision = API.FontClipPrecision.CLIP_DEFAULT_PRECIS   
        m_LogFont.lfQuality = API.FontQuality.DEFAULT_QUALITY   
        m_LogFont.lfPitchAndFamily = API.FontPitchAndFamily.DEFAULT_PITCH Or API.FontPitchAndFamily.FF_ROMAN   
  
        ptrLogFont = Marshal.AllocHGlobal(Marshal.SizeOf(m_LogFont))   
        Marshal.StructureToPtr(m_LogFont, ptrLogFont, False)   
  
        m_cf.lStructSize = Marshal.SizeOf(m_cf)   
        m_cf.hwndOwner = _hWnd   
        m_cf.lpLogFont = ptrLogFont   
        m_cf.iPointSize = m_Font.SizeInPoints * 10   
        m_cf.flags = GetFlags()   
        m_cf.lpfnHook = New API.CFHookProcDelegate(AddressOf HookProc)   
        m_cf.rgbColors = m_Color.B   
        m_cf.rgbColors = m_cf.rgbColors << 8   
        m_cf.rgbColors = m_cf.rgbColors Or m_Color.G   
        m_cf.rgbColors = m_cf.rgbColors << 8   
        m_cf.rgbColors = m_cf.rgbColors Or m_Color.R   
        m_cf.nSizeMax = 0   
        m_cf.nSizeMin = 0   
    Catch ex As Exception   
        MsgBox("Error Creating CF Strucure: " &ex.Message)   
        Return False  
    End Try  
End Function

Open in new window

0
Comment
Question by:tim8w
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 21826087
I am confused--do you want to have a font selection dialog?
0
 

Author Comment

by:tim8w
ID: 21827087
TheLearnedOne,
My original problem was that I couldn't set the initial StartPosition of any of the CommonDialogs in .Net. So I have reverted back to the API versions and have gotten GetOpenFileName, GetSaveFileName and ChooseColor to work by adding a HookProc and positioning the dialog to where the user wants it to be. Then when I got to the ChooseFont dialog, I get the error described in my original question when I attampt to set the HookProc...

Hope that clears things up.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 21827438
I wonder if this trick still works:

http://www.devx.com/tips/Tip/12238

If you are you unhappy with Microsoft's comment in the help ("Note: You cannot specify where a common dialog box is displayed"), but like the idea of common dialog controls, try this.

Start a hidden dummy form instead of calling the open dialog box directly from your main form:

(frmDummy_OpenSaveAs.Hide),

Define the Left and Top properties as you wish and then start the common dialog box from this form. On a Windows 95 system using the 32-bit version of Visual Basic, the open dialog box appears exactly over the left/top coordinates of the form that called the dialog box. This also works if the calling form is hidden and not visible to the user.
0
Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

 

Author Comment

by:tim8w
ID: 21828751
Regardless of that Microsoft comment, you can specify where a common dialog box is displayed, as I've already done it for three other common dialogs. Hasn't anyone ever used the HookProc for the ChooseFont dialog? I find this very hard to believe...
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 21830039
I haven't, because it is a common dialog, and I don't care where it shows up.
0
 

Accepted Solution

by:
tim8w earned 0 total points
ID: 21834363
Since I have been creating solutions for all the Common Dialogs, I ended up with a copy & paste bug. To enable the Hook I was setting the Flag from ChooseColorFlags instead of the one from ChooseFontFlag. Once I changed it to the right Flag, everything worked just fine.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

1.0 - Introduction Converting Visual Basic 6.0 (VB6) to Visual Basic 2008+ (VB.NET). If ever there was a subject full of murkiness and bad decisions, it is this one!   The first problem seems to be that people considering this task of converting…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This is a high-level webinar that covers the history of enterprise open source database use. It addresses both the advantages companies see in using open source database technologies, as well as the fears and reservations they might have. In this…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

729 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question