Thread: Button positioning

  1. #16
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    Try this function inside WM_SIZE. Pass your button handle as the parameter.

    Code:
    /*
     *  Places a control at the bottom right of it's parent.
     */
    void MakeBottomRight( HWND button )
    {
      RECT rcClient, rcButton ;  
      HWND hwndParent ;
      int newButtonX, newButtonY ;
      
      if ( !IsWindow(button) )
        return ;
      
      hwndParent = GetParent(button);
      
      if ( !IsWindow(hwndParent) )
        return ;
      
      GetClientRect( hwndParent, &rcClient );  
      GetClientRect( button, &rcButton );  
      newButtonX = rcClient.right  - rcButton.right  ;
      newButtonY = rcClient.bottom - rcButton.bottom ;  
      SetWindowPos( button, NULL, newButtonX, newButtonY, 0, 0, 
                    SWP_NOSIZE|SWP_NOZORDER );
    }
    Last edited by Dante Shamest; 10-10-2005 at 06:36 PM.

  2. #17
    Registered User
    Join Date
    May 2005
    Posts
    207
    Um... I can't get that code to work. I don't know how to pass a value to a windows procedure (I can pass values in C though).

    Also it's telling me "missing ';' before 'type'" on the void MakeBottomRight line. The WM_SIZE worked fine before I added the function (!?)

    mw
    Blucast Corporation

  3. #18
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    Put that piece of code at the top. Probably below your <windows.h>

    Then in your WM_SIZE message, call it like this:

    Code:
        case WM_SIZE:
          {
            MakeBottomRight( hwndButton );
            return 0 ;
          }
    For reference, this is my complete code.

    Code:
    /*------------------------------------------------------------------------------
    Demonstrates putting a button at the bottom right of a window.
      
    Author: Dante Shamest
    Date:   11th October 2005
    ------------------------------------------------------------------------------*/
    #include <windows.h>
    
    HWND hwndMain ;
    HWND hwndButton ;
    
    /*
     *  Places a control at the bottom right of it's parent.
     */
    void MakeBottomRight( HWND button )
    {
      RECT rcClient, rcButton ;  
      HWND hwndParent ;
      int newButtonX, newButtonY ;
      
      if ( !IsWindow(button) )
        return ;
      
      hwndParent = GetParent(button);
      
      if ( !IsWindow(hwndParent) )
        return ;
      
      GetClientRect( hwndParent, &rcClient );  
      GetClientRect( button, &rcButton );  
      newButtonX = rcClient.right  - rcButton.right  ;
      newButtonY = rcClient.bottom - rcButton.bottom ;  
      SetWindowPos( button, NULL, newButtonX, newButtonY, 0, 0, 
                    SWP_NOSIZE|SWP_NOZORDER );
    }
    
    LRESULT CALLBACK WndProc( HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam )
    {
      switch(msg)  
      {
        case WM_CREATE:
          {
            hwndButton = CreateWindow( "BUTTON", "My Button", WS_CHILD|WS_VISIBLE,
                                       10, 10, 200, 22, hwnd, 0, GetModuleHandle(0),
                                       0 );
                                       
            return 0;                                    
          }
          
        case WM_SIZE:
          {
            MakeBottomRight( hwndButton );
            return 0 ;
          }
        
        case WM_DESTROY:
          {
            PostQuitMessage(0);
            return 0;
          }
          
        default: return DefWindowProc(hwnd,msg,wParam,lParam);
      }
    }
    
    int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrev, LPSTR args, int nShow )
    {
      WNDCLASS wc = {0};
      MSG  msg ;    
      wc.lpszClassName = TEXT( "ButtonFun" );
      wc.hInstance     = hInst ;
      wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
      wc.lpfnWndProc   = WndProc ;
      wc.hCursor       = LoadCursor(0,IDC_ARROW);
      
      RegisterClass(&wc);
      hwndMain = CreateWindow( wc.lpszClassName,TEXT("Button At Lower Right"),
                               WS_OVERLAPPEDWINDOW|WS_VISIBLE,
                               0,0,300,200,0,0,hInst,0);
      
    
      while( GetMessage(&msg,0,0,0) > 0 ) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
      }
      return (int)msg.wParam;
    }
    Last edited by Dante Shamest; 10-10-2005 at 06:37 PM.

  4. #19
    Registered User
    Join Date
    May 2005
    Posts
    207
    I'm still getting a bunch of errors/warnings, starting with "Illegal use of HWND" in the line that says "HWND hwndParent = GetParent(button);"

    I'm sorry for being so much trouble man... :-(

    I can probably print a button in the bottom right hand corner myself. Is that all you were wanting me to do? It probably won't print in the DISPLAYED bottom right hand corner though...

    mw
    Blucast Corporation

  5. #20
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    Just want to check something. Are you using C, or C++?

    And yes, basically my C++ function puts the button (or any control) at the bottom of its parent window.

  6. #21
    Registered User
    Join Date
    May 2005
    Posts
    207
    I'm using C.

    This is my button:

    hwndButton = CreateWindow
    (
    TEXT ("button"),
    TEXT ("New Game"),
    WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
    rect.right - btnWidth,
    rect.bottom - btnHeight,
    btnWidth,
    btnHeight,
    hwnd,
    (HMENU) IDB_NEWGAMEBUTTON,
    GetModuleHandle (NULL),
    NULL
    );

    This is supposed to display the button as far to the right as it can and as far to the bottom as it can.

    It displays the button approx 75% to the right and 75% to the bottom of the client area.

    mw
    Blucast Corporation

  7. #22
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    Okay, I've changed my code to be C. It should work now.

  8. #23
    Registered User
    Join Date
    May 2005
    Posts
    207
    Much better!

    Ok, now it gives me the warning "hwndButton used without having been initialized". I added the CreateWindow command to my WM_CREATE just like you did and it still gives me this warning.

    It doesn't print any button(s)...

    mw
    Blucast Corporation

  9. #24
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    Have you assigned the button handle to hwndButton using the = operator?

  10. #25
    Registered User
    Join Date
    May 2005
    Posts
    207
    Ok, two things:

    1) I had defined HWND locally instead of globally like you did.

    2) It works beautifully now and prints a non-clickable button in the very bottom right hand corner of the DISPLAYED client area with "My Button" text on it.

    I guess this means I'm doing it wrong somehow...

    Thanks for your patience, BTW!

    What does this mean?

    mw
    Blucast Corporation

  11. #26
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    Glad that there's finally some results.

    I'm not sure what you're doing that's different, but instead of specifying the size in CreateWindow(Ex), calculate the position of the button in WM_SIZE, then use MoveWindow or SetWindowPos to change the button's position.

  12. #27
    Registered User
    Join Date
    May 2005
    Posts
    207
    I think I figured out why I can't center my buttons properly:

    When I declare my window class, I use CW_DEFAULT for the width/height settings. I create the buttons immediately after declaring the window. When I finally ShowWindow I specify it as maximized.

    How do I change my window declaration to be maximized? You have to specify width/height instead of just saying "maximized" and Charles Petzold (of course) doesn't seem to have any information in his lousy book... :-(

    mw
    Blucast Corporation

  13. #28
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    How do I change my window declaration to be maximized?
    You mean in CreateWindow(Ex)? You'll have to calculate the size of the screen, and subtract the taskbar height.

    Why not just do all your calculations in WM_SIZE? (e.g., in the code I posted above)

  14. #29
    Registered User
    Join Date
    May 2005
    Posts
    207
    My boss wants the window full screen and unchangeable (ie: WS_OVERLAPPED instead of WS_OVERLAPPEDWINDOW). :-(

    mw
    Blucast Corporation

  15. #30
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    My boss wants the window full screen and unchangeable
    Fullscreen (and not just maximized)? Then that's easy. Use the following values as the width and height.

    Code:
      int screenWidth  = GetSystemMetrics(SM_CXSCREEN) ;
      int screenHeight = GetSystemMetrics(SM_CYSCREEN) ;

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 06-28-2008, 08:30 PM
  2. elliptical button
    By geek@02 in forum Windows Programming
    Replies: 0
    Last Post: 11-21-2006, 02:15 AM
  3. Remove dialog button border
    By RedZone in forum Windows Programming
    Replies: 4
    Last Post: 08-21-2006, 01:20 PM
  4. writing text over a deleted button
    By algi in forum Windows Programming
    Replies: 4
    Last Post: 05-02-2005, 11:32 AM
  5. Window won't display on button command!?
    By psychopath in forum Windows Programming
    Replies: 6
    Last Post: 06-22-2004, 08:12 PM