• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 475
  • Last Modified:

PathCompactPath parameters

I want to use the PathCompactPath API to make a long file name fit into a fixed label width. The API guide I have lists three parameters: the string with the path name, the maximum width in pixels, and "hDC: Handle to the device context used for font metrics." The first two are obvious; the third one has me baffled, and checking a number of online references to the API hasn't helped. Some of them have VB code that uses "Me.hDC" as this parameter passed, but it I try that I get an error of "hdc is not a member of frmMain." And really I wouldn't expect to refer to something at the form level; I would think what I really want to pass is a Font. But the parameter is supposed to be a Long, so a Font won't work. I see a GetHDC method for Graphics objects, which sounds like it might be usable as part of this, but I don't see how to associate a font with that without actually drawing something on the form, which I'm not interested in doing.
0
ElrondCT
Asked:
ElrondCT
  • 5
  • 4
  • 3
  • +1
4 Solutions
 
Bob LearnedCommented:
Dim gr As Graphics = Me.CreateGraphics()
Dim hDC As IntPtr = gr.GetHdc()

Define the parameter for hDC in the API function to IntPtr.

Bob
0
 
Fernando SotoRetiredCommented:
Hi ElrondCT;

With Bob's help here is some code

    Private Declare Function PathCompactPath Lib "shlwapi.dll" _
        Alias "PathCompactPathA" _
        (ByVal hDC As IntPtr, _
        ByVal pszPath As StringBuilder, _
        ByVal dx As Integer) As Integer

    Const MAX_PATH As Integer = 260

    Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click

        Dim gr As Graphics = Label1.CreateGraphics()
        Dim hDC As IntPtr = gr.GetHdc()
        Dim str As New StringBuilder(MAX_PATH)
        str.Append("C:\Temp\Download\Today\file\size\Thefile.txt")
        Dim dx As Integer = Label1.Size.Width
        Dim ret As Integer

        ret = PathCompactPath(hDC, str, dx)
        If Not ret = 0 Then
            Label1.Text = str.ToString()
        End If


    End Sub


Fernando
0
 
ElrondCTAuthor Commented:
Thanks to both of you. I didn't realize controls could execute the CreateGraphics method. I've got it mostly working, though I'm finding that the width measurement doesn't seem to be precise--I had to increase the width about 1.2x the width of the label, and when I resize, I can't develop an algorithm that keeps the whole label filled without going over (when I increase the size, it doesn't get large enough, and when I decrease the size, it doesn't shrink enough). In addition, after I play with resizing for a bit, the program crashes with an InvalidOperationException: "The object is currently in use elsewhere." I wondered if it was because I wasn't disposing the graphic, and lots of resizes were causing a stack overflow, but when I put a gr.Dispose() in, I started getting the exception as soon as the program started. However, I don't expect someone to want to do much resizing of the form (it's filled with fixed-width controls), so I think I can live with it as it is. (I'm not using the exact Sub posted, because when I tried to do that, I got an arithmetic overflow error on the API call. But I pulled the ideas into a Sub I had half-written, and that's what's working for me.)

FernandoSoto, what is the purpose of using the stringbuilder, rather than a simple string of the path?
0
Industry Leaders: 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!

 
Mike TomlinsonMiddle School Assistant TeacherCommented:
You could also draw the string yourself using Graphics.DrawString() with the StringFormat.StringTrimming.EllipsisPath flag as in this example:
http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/VB_DOT_NET/Q_21407534.html
0
 
ElrondCTAuthor Commented:
Drawing the string directly doesn't work, because this is actually going into a panel of a status bar, not a label. Thanks anyway.
0
 
Fernando SotoRetiredCommented:
Hi ElrondCT;

To your question, "what is the purpose of using the stringbuilder, rather than a simple string of the path?". Because the String Class is a immutable object and the non .Net API will change its value I feel that it is safer to use a class that would not have to be recreated when the value is changed.

Fernando
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
As a general rule of thumb...whenever YOU get a graphics via CreateGraphics() you should manually dispose of that Graphics as soon as you no longer need it:

    Dim gr As Graphics = Label1.CreateGraphics()
    ...
    gr.Dispose()
0
 
ElrondCTAuthor Commented:
Idle_Mind, unfortunately the exception problem became worse when I put the Dispose method into my code. My actual code, in both the Form Resize sub and my File Open sub, is:

            Dim strCompactFile As String = strFullFile
            Dim g As Graphics = StatusBar1.CreateGraphics
            Dim hDC As IntPtr = g.GetHdc()
            PathCompactPath(hDC, strCompactFile, ToInt64(sbpFile.Width * 1.2))
            sbpFile.Text = "File: " & strCompactFile
            strCompactFile = Nothing
            'g.Dispose()

When I uncomment the g.Dispose(), I get the InvalidOperationException: "The object is currently in use elsewhere" as soon as the form loads. When I have it commented out, the exception pops up only after doing a substantial amount of resizing. And I don't really expect my users to be doing any resizing at all, because there's no benefit to them of doing it, though at this point I'm not preventing it.
0
 
Bob LearnedCommented:
Sorry, my bad :(

The graphics object is in use here:

  g.GetHdc()

You need to release the hDC before you can dispose of the Graphics instance:

  g.ReleaseHdc(hDC)

Bob
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Thanx Bob...was just about to post that as well...   =)
0
 
Bob LearnedCommented:
It seems like a tag team thing sometimes, huh?  ;)  =:)

Bob
0
 
ElrondCTAuthor Commented:
That makes sense; I should have thought about that. I discovered that "Hide advanced members" was turned on for statement completion so Intellisense wasn't displaying methods like ReleaseHdc, which didn't make it any easier... I now seem to be in good shape on resizing as far as not crashing, though I don't understand why the measurement I'm giving PathCompactPath isn't working quite right. But again, I don't expect much resizing, so that's not important.

I appreciate everyone's help. I'm very much still in learning mode on VB, and since I'm a one-man computer department, your assistance is invaluable. There's so much I don't know that it seems rather scary that I'm more than halfway to EE's "master" level with the questions I've answered here, but I guess that means I'm actually learning something!
0
 
Bob LearnedCommented:
Yeah, with the amount of questions asked, you can just keep answering the same questions over and over again, and pile up the points and not learn many new things.

Bob
0
 
ElrondCTAuthor Commented:
Well, I often will intentionally look at questions that I don't know the answer to, if they seem relevant to what I am or might soon be doing, and I'm gleaning a lot of ideas from what the rest of you post. (Whether I'll remember them when I need them is another question.) I've been programming for a long time (longer than some of the people here have been alive), but had only dabbled in object-oriented programming before last year, so there's a lot of new stuff to learn. Nonetheless, I'm finding that a lot of the "tricks of the trade" do carry over from one language to another, which is part of what enables me to answer questions here.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 5
  • 4
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now