Thread: Groupboxes (and a couple of other Win32 questions)

  1. #1
    Registered User
    Join Date
    Jul 2015
    Posts
    64

    Groupboxes (and a couple of other Win32 questions)

    Good evening Cboard!

    I have been programming as a hobby, on and off, for the past seven years or so and have recently decided to take the plunge into Windows programming. Currently, I am creating a frame-based GUI from scratch, including a couple of groupboxes generated with CreateWindow().

    Along with the controls within the box, I wish to display the text stored in an std::string variable called sBracedUser. My current method, based on the TextOut() API, is failing; if I set the first parameter to the function (HWND) as the handle to the groupbox's parent window, the program does indeed print the text, but cannot print it on top of the groupbox. If I set the handle parameter of TextOut() as the handle to the groupbox, the function fails. The relevant code sections are as follows:

    Global typedef of String (for ANSI and Unicode builds respectively):
    Code:
    #ifndef UNICODE
      typedef std::string String;
    #else
      typedef std::wstring String;
    #endif
    This is my OutputTextToWindow() function:
    Code:
    int OutputTextToWindow(HWND hwnd, String text, int xpos, int ypos)
    {
        HDC hDeviceContext = GetDC(hwnd);       // Get handle to device context
        
        HGDIOBJ NewFont = GetStockObject(DEFAULT_GUI_FONT);              // Create NewFont object.
        HGDIOBJ OldFont = SelectObject(hDeviceContext, NewFont);         // Load NewFont into hDevice Context
                                                                         // N.B. Displaced font in HDC must be reloaded again
        SetBkMode(hDeviceContext, TRANSPARENT);                          // Set text background as transparent
        
        TextOut(hDeviceContext, xpos, ypos, text.c_str(), text.length());    // Print text
        
        SelectObject(hDeviceContext, OldFont);      // Clean up - OldFont is reloaded into DC
        DeleteObject(OldFont);                      //            OldFont object is deleted
        DeleteObject(NewFont);                      //            NewFont object is deleted
        ReleaseDC(hwnd, hDeviceContext);            //            Device context is released
        
        return 0;
    }
    This code is in a control-creation function:
    Code:
    HWND hUsersBox = CreateWindow(_T("BUTTON"), _T("Select Users"), BS_GROUPBOX | WS_CHILD, 9, 10, 232, 235, hwnd, NULL, hInstance, NULL);
    
    // More code in between these lines.
    
    String sBracedUser = BraceEnclosure(lpUser, Size);      // Initialise String and set it equal to (<username>).
    
    // More arbitrary code.
    
    ShowWindow(hUsersBox, SW_SHOW);
    OutputTextToWindow(hwnd, sBracedUser.c_str(), 50, 150);    // Output user name in brackets.
    
    // OutputTextToWindow(hUsersBox, sBracedUser.c_str(), 50, 150) fails due to failure of the TextOut() function.
    Obviously the code needs alot more work to manage error-checking etc. I was just wondering if there is any way to modify the text output function to allow printing text to a groupbox object. Or would a completely different approach entirely be necessary, perhaps because, by design, the Win32 API forbids the TextOut() function to interact with non-window objects?

    My other question about the Win32 API is a quick one. All of the sample code I have found for basic window creation initialise the classname variable for WNDCLASSEX as a global variable. Is this strictly necessary? As far as I'm aware, the only use for this would be for calls to CreateWindow/CreateWindowEx in functions other than the original window-creation function.

    Any help would be greatly appreciated!
    Many thanks,
    Abyssion

    P.S. This is slightly off topic, I apologise: does this site not allow for SSL connections to the forum servers? I am very wary, in general, of sending user credentials in plaintext over the internet. Cheers.
    Last edited by Abyssion; 07-17-2015 at 12:33 PM.

  2. #2
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    Try using the SetWindowText(hwnd, pszString) function, hwnd is handle to the group box control, and pszString is pointer to null terminated string.

    A group box is a type of button control, and the text in the group box is an attribute of the control. So you cannot write text to it as you would to a window using TextOut().

    -
    Last edited by megafiddle; 07-18-2015 at 11:44 PM.

  3. #3
    Registered User
    Join Date
    Jul 2015
    Posts
    64
    Many thanks for the reply Mega!
    Unfortunately, that wasn't quite what I was looking for. I apologise, I should have been clearer.

    My intention was to print the username underneath the text of a radiobutton in the groupbox. I actually hadn't considered the fact that radiobuttons, like normal button controls, can handle the BS_MULTILINE style until today, so if I just append '\n' followed the username string to the radiobutton's caption, the text will wrap and my problem is pretty much solved.

    However, curiosity has now gotten the best of me and I'm wondering if there is a way to arbitrarily output text to a specific given position on the *inside* of a groupbox, as oppose to changing it's caption at the top? Since conventional methods seem to fail, is it perhaps possible to use some perverse parent-window-tracking technique in which text is printed onto a transparent child window in position above the groupbox and have the child window "follow" the parent around if it is moved by the user?

    Also, any insights into the classname variable and SSL thing would be greatly appreciated
    Thanks again, man!

  4. #4
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    Oh, sorry.

    Not sure how versatile you need it to be, but the text could be set in a static control, which could then be positioned anywhere within the group box. With the text aligned to the left within the static control, the x,y position of the control is effectively the x,y position of the text.

    A global (or static) initialization of the classname char array might simply be left over from early versions of C, which did not allow initialization of non static arrays. In "Programming Windows" - Charles Petzold, the classname variable is either global, or declared as static inside WinMain().

    -

  5. #5
    Registered User
    Join Date
    Jul 2015
    Posts
    64
    Ahh, thanks very much for the pointer, I shall have a look into static controls for future reference.

    That makes a lot of sense; I actually had no idea that earlier versions of C didn't like non-static array initialisation. Cheers for the clarification; it's been something that's bugged me about Windows sample code for years!

    Cheers Mega!

  6. #6
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    I still use static initializations for strings, but for other reasons, though (just my own programming philosophy).

    Cheers Abyssion!

    -

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Couple of questions
    By mr_raging_money in forum C Programming
    Replies: 4
    Last Post: 03-27-2012, 08:11 AM
  2. Just a couple of questions
    By redsfan in forum C++ Programming
    Replies: 5
    Last Post: 04-13-2011, 10:13 AM
  3. Groupboxes in Win32 API
    By maxorator in forum Windows Programming
    Replies: 2
    Last Post: 10-01-2006, 04:04 AM
  4. Couple questions
    By random in forum C++ Programming
    Replies: 7
    Last Post: 08-19-2005, 07:29 PM
  5. A couple questions
    By Flakster in forum C++ Programming
    Replies: 7
    Last Post: 08-09-2005, 01:22 PM

Tags for this Thread