CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    May 2011
    Posts
    45

    How to resize a combo box?

    I have a combo box that contains a list of user defined project names, including an entry to add another project. Project names are generally short, but someone could easily add a long name. If they do, I’d like to be able to resize the combo box to display the entire name. To do this I’d have to “ask” the system how many pixels wide each project name is:
    Code:
    WidthOfName = HowWideIs(“Very Long Project Name”,”Microsoft Sans Serif, 11pt”);
    Then I could find the widest name and resize the combo box and also move the “Local Path” label that follows the box.

    So, is there such a system call? And, if so, what is the proper syntax?

  2. #2
    Join Date
    May 2011
    Posts
    45

    Re: How to resize a combo box?

    Oh, it just keeps getting better! I managed to find a reference to a Measure String function.
    My combo box is defined as:

    Code:
    // 
    // websiteName
    // 
    this->websiteName->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 
                               11, System::Drawing::FontStyle::Regular, 
                               System::Drawing::GraphicsUnit::Point, 
                               static_cast<System::Byte>(0)));
    this->websiteName->FormattingEnabled = true;
    this->websiteName->Location = System::Drawing::Point(52, 20);
    this->websiteName->Name = L"websiteName";
    this->websiteName->Size = System::Drawing::Size(121, 26);
    this->websiteName->TabIndex = 0;
    this->websiteName->SelectedIndexChanged += 
              gcnew System::EventHandler(this, &Form1::websiteName_SelectedIndexChanged);
    I read in an INI file during the form load process where I extract the project names, then I want to use the Measure String function to determine the maximum length of the names. But I’m gettign another of those static vs non-static error messages and I can’t figure out how to get around this one!

    Code:
    private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e)
    {
    . . .
    String ^ name = line->Substring(0,tabpoint);
    . . .
    System::Drawing::SizeF width = Graphics::MeasureString(name,this->websiteName->Font);
    error C2352: 'System :: Drawing :: Graphics :: MeasureString' : illegal call of non-static member function

  3. #3
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: How to resize a combo box?

    Actually, I would just have recommended you to use Graphics::MeasureString() if you wouldn't have been quicker finding it. However, as you have experienced, this is an instance method and thus needs to be called on a Graphics object. That object can be obtained in a number of ways, but as you want to calculate how much space a certain string will take up when painting a control, the natural way to get the Graphics instance is Control::CreateGraphics().

    A small example of using MeasureString() can be found at http://www.codeguru.com/forum/showth...=MeasureString. However, this is a quite early C++/CLI code sample of mine, and nowadays I'd use CreateGraphics() as recommended above instead of that hackish way of obtaining it from the control's HWND. (I also would have used String::Format() instead of String::Concat() and ToString(), but of course that's completely unrelated to the use of the Graphics object and MeasureString().)

    Finally, I'd recommend to use care when choosing between the various overloads of MeasureString(). It may, for instance, be preferable to use one that takes a StringFormat parameter to enable you to do some typographic fine-tuning. That's something I'm still struggling with a bit myself when using that method.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  4. #4
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: How to resize a combo box?

    Quote Originally Posted by PapaGeek View Post
    My combo box is defined as:
    Code:
    this->websiteName->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 
                               11, System::Drawing::FontStyle::Regular, 
                               System::Drawing::GraphicsUnit::Point, 
                               static_cast<System::Byte>(0)));
    ...
    You're probably better of using Control::DefaultFont rather than hard-coding a font in there.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  5. #5
    Join Date
    Jul 2002
    Posts
    2,543

    Re: How to resize a combo box?

    Quote Originally Posted by D_Drmmr View Post
    You're probably better of using Control:: DefaultFont rather than hard-coding a font in there.
    Good idea, but this code is probably generated by designer

  6. #6
    Join Date
    May 2011
    Posts
    45

    Re: How to resize a combo box?

    Thanks for all the help, it is working fine now, just have to add the code to change the combo box size.

    I added the line
    Code:
     Graphics ^gr = Graphics::FromHwnd(this->websiteName->Handle);
    At the start of the loop that reads in the data, and changed the actual call to:
    Code:
    SizeF width = gr->MeasureString(name,this->websiteName->Font);
    Feedback::TraceLine(name + ": " + width);
    I expected the results to be in whole pixels, but its easy enough to round everything up:

    Code:
    HowTo: {Width=52.73458, Height=18.43359}
    Papa: {Width=40.16622, Height=18.43359}
    PapaGeek: {Width=76.27429, Height=18.43359}
    Very Long Project Name: {Width=168.9722, Height=18.43359}

    The response that was the key, and also the most confusing to an old school C / C++ programmer was: “However, as you have experienced, this is an instance method and thus needs to be called on a Graphics object.” But you guys are slowly teaching this old dog new tricks and it is well appreciated.


    Alex,

    You are correct, the font code is being generated by the designer.

  7. #7
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: How to resize a combo box?

    Quote Originally Posted by PapaGeek View Post
    Thanks for all the help, it is working fine now, just have to add the code to change the combo box size.
    Fine! And, of course, you'rewelcome.

    However...

    I added the line
    Code:
     Graphics ^gr = Graphics::FromHwnd(this->websiteName->Handle);
    As already mentioned in post #3, the simpler way to do that is:

    Code:
     Graphics ^gr = websiteName->CreateGraphics();
    I don't think that makes any difference regarding program behavior for now, it's just simpler. It may make a difference some time in the future, however, if MS decides to change some implementations.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  8. #8
    Join Date
    May 2011
    Posts
    45

    Re: How to resize a combo box?

    I’m a little confused here, what else is new – SMILE !

    My original attempt called Measure String as: Graphics::MeasureString from Form1_Load. If I understand what is going on, Form1_Load is a non-static member function of the form. Isn’t the Graphics::MeasureString syntax a call to the static function? Can’t a non-static function call a static function? In fact, a few lines after that call I call my own static function Feedback::TraceLine and that doesn’t complain.

    So, what is the difference here? Why can’t I call the static Measure String function?

  9. #9
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: How to resize a combo box?

    Quote Originally Posted by PapaGeek View Post
    If I understand what is going on, Form1_Load is a non-static member function of the form.
    Correct.

    Isn’t the Graphics::MeasureString syntax a call to the static function?
    If it's actually a call you're writing that way, then yes - in most cases. However, this syntax is also commonly used when writing non-source-code text about functions, to denote which class the function (or, for that matter, any other class member) is a member of. An alternative way of denoting this could be, for instance, anyVariableOfTypeGraphics->MeasureString(). But doesn't that look rather awkward and uncanonical? Also, it would be practically impossible to specify the namespace along with the class and function that way, which is unproblematic when using the scope resolution operator ::.

    Actually, there are situations where the scope resolution operator is used in the context of instance methods in source code (aside from their definition, of course): Say you have a class derived from Form, in which you have overridden the ShowDialog() method. Now you want to call the base class implementation of that method from your override. Which syntax do you use?

    Code:
    Form::ShowDialog();
    (IMO using the __super keyword in this situation is the preferable alternative, but that keyword is MS-specific and thus not part of the active vocabulary of many developers used to traditional C++.) You don't specify the object to call the instance method on here; it's implicitly called on *this.

    Another situation where the scope resolution operator is used on instance methods is when passing the method as such as a function parameter, as opposed to the result of calling the method. Probably the most common use case for that in C++/CLI is calling delegate constructors:

    Code:
          this->txtCmdLine->TextChanged += gcnew System::EventHandler(this, &Form1::txtCmdLine_TextChanged);
    Can’t a non-static function call a static function?
    Yes, without any restrictions except those imposed by member visibility rules. However, when calling an instance method from a static one, you'll need to specify the object to call it on in any case, even if the two belong to the same class. That's because static methods aren't object-bound, so they don't have a *this the instance method could implicitly be called on.

    In fact, a few lines after that call I call my own static function Feedback::TraceLine and that doesn’t complain.
    Yes, that's because Feedback::TraceLine() actually is a static method.

    So, what is the difference here? Why can’t I call the static Measure String function?
    As pointed out above, you were the victim of a not-so-uncommon misunderstanding here. You have seen that the use of the scope resolution operator in text discussing a method is no certain indication it is static. On MSDN, static members have a big fat red S next to it in the list of members, and also, of course, the static keyword in the in the prototype at the top of the page describing the member. As to other clases, there's no way to tell for sure without consulting the .h file or other documentation.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured