Link to home
Start Free TrialLog in
Avatar of ElrondCT
ElrondCTFlag for United States of America

asked on

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.
SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ElrondCT

ASKER

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?
You could also draw the string yourself using Graphics.DrawString() with the StringFormat.StringTrimming.EllipsisPath flag as in this example:
https://www.experts-exchange.com/questions/21407534/Shorten-filepath-with-ellipsis.html
Drawing the string directly doesn't work, because this is actually going into a panel of a status bar, not a label. Thanks anyway.
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
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanx Bob...was just about to post that as well...   =)
It seems like a tag team thing sometimes, huh?  ;)  =:)

Bob
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!
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
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.