Thread: drawing column label boxes

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    26

    drawing column label boxes

    I am trying to draw a series of rectangles to use as column headers(as well as eventually list tables full of data below it. I have a sorta primitive solution that should work as far as I can tell but it seems to just make the screen into two rectanges instead of seven rectanges near the top. Here is the code to draw them:
    Code:
    			SetMapMode(hdc, MM_TEXT);
    			GetClientRect (hWnd, &rect) ;
    			GetTextMetrics (hdc, &tm) ;
    			a=0;
    			y=0;
    			if(iPartyMemb==0){
    				MessageBox(hWnd, TEXT("Party is loaded but with no members"), TEXT("Party is loaded with no members"),MB_OK);
    			}
    			SelectObject(hdc, GetStockObject(SYSTEM_FONT));
    			SelectObject(hdc, GetStockObject(WHITE_BRUSH));
    			SelectObject(hdc, GetStockObject(BLACK_PEN));
    			a=cxArea/7;
    			b=tm.tmHeight;
    
    			SetRect( &MyLabels.name, rect.left, rect.top, a, rect.top + b);
    			SetRect( &MyLabels.height, rect.left + a, rect.top, rect.right + (2 * a), b);
    			SetRect( &MyLabels.weight, rect.left + (2 * a), rect.top, rect.right + (3 * a), b);
    			SetRect( &MyLabels.drug1, rect.left + (3 * a), rect.top, rect.right + (4 * a), b);
    			SetRect( &MyLabels.drug2, rect.left + (4 * a), rect.top, rect.right + (5 * a), b);
    			SetRect( &MyLabels.drug3, rect.left + (5 * a), rect.top, rect.right + (6 * a), b);
    			SetRect( &MyLabels.symptoms, rect.left + (6 * a), rect.top, rect.right + (7 * a), b);
    
    			FrameRect(hdc, &MyLabels.name,(HBRUSH)GetStockObject(BLACK_BRUSH));
    			FrameRect(hdc, &MyLabels.height,(HBRUSH)GetStockObject(BLACK_BRUSH));
    			FrameRect(hdc, &MyLabels.weight,(HBRUSH)GetStockObject(BLACK_BRUSH));
    			FrameRect(hdc, &MyLabels.drug1,(HBRUSH)GetStockObject(BLACK_BRUSH));
    			FrameRect(hdc, &MyLabels.drug2,(HBRUSH)GetStockObject(BLACK_BRUSH));
    			FrameRect(hdc, &MyLabels.drug3,(HBRUSH)GetStockObject(BLACK_BRUSH));
    			FrameRect(hdc, &MyLabels.symptoms,(HBRUSH)GetStockObject(BLACK_BRUSH));
    The other thing I wanted to know is how could I make columns sorta similar to how they make them in like excel where I could adjust them and all durring running?

  2. #2
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Unless you're intent on re-inventing the wheel use a listview common control.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    26
    I'm not trying to make Icon bar(to be honest I don't think I have enough functions in my program to need a icon bar). Basically I am making a spreadsheet/table(not directly modifiable by the user). I just am trying to make a bar to label all the columns. I would like to make it resizable but that is not a neccesaty. I can't do each column as seperate child windows becuase each row is going to be seperate child windows.

    Any suggestions?

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Have a look at the screen-shot at the bottom of this listview sample.

    As for your code, it looks alright, except that it doesn't show how cxArea is initialised, so I'd check that first.

  5. #5
    Registered User
    Join Date
    Apr 2007
    Posts
    26
    Thank you. That is exactly what I wanted!!

    I just have one small question. Is there anyway to make it so that the columns are boxed in? Similar to how excel has it where there is a gray or black box surronding each of the blocks?

  6. #6
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Did you try novacain's suggestion? Note that LVS_EX_GRIDLINES must be set using ListView_SetExtendedListViewStyle. Screen-shot here.

  7. #7
    Registered User
    Join Date
    Apr 2007
    Posts
    26
    Oh sorry. must of missed that.
    It all works wonderfully execpt for one thing...It will not display properly untill I click on the window. If I do anything to the window to make it redraw(resize, minimize, maximize, InvalidateRect (hWnd, NULL, TRUE) ; ) I have to click a second time on the window to get it to display anything but the menu bar. It only does this when the listview window is displayed.

    Here is my list view code(as you can tell it is a very unmodified version from that link):
    Code:
    			LVCOLUMN lvc = { 0 };
    			LVITEM   lv  = { 0 };
    			
    			GetClientRect(hWnd, &rt);
    
    			UserTbl = CreateWindow(WC_LISTVIEW,
                                     NULL,
                                     WS_CHILD | WS_VISIBLE | LVS_REPORT,
    								 rt.left,
    								 rt.top,
    								 rt.right,
    								 rt.bottom,
                                     hWnd,
                                     (HMENU) 500,
                                     hInst,
                                     NULL);
    
    			ListView_SetExtendedListViewStyle(UserTbl,LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP | LVS_NOSCROLL | LVS_EX_GRIDLINES);
    			
    			lvc.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH  | LVCF_FMT;
    			lvc.fmt  = LVCFMT_CENTER;
    
    			/* Add four columns to the list-view (first column contains check box). */
    			lvc.iSubItem = 0;
    			lvc.cx       = 150;
    			lvc.pszText  = TEXT("Name");
    			ListView_InsertColumn(UserTbl, 0, &lvc);
    
    			lvc.iSubItem = 1;
    			lvc.cx       = 150;
    			lvc.pszText  = TEXT("Height");
    			ListView_InsertColumn(UserTbl, 1, &lvc);
    
    			lvc.iSubItem = 2;
    			lvc.cx       = 150;
    			lvc.pszText  = TEXT("Weight");
    			ListView_InsertColumn(UserTbl, 2, &lvc);
    
    			lvc.iSubItem = 3;
    			lvc.cx       = 150;
    			lvc.pszText  = TEXT("Drug 1");
    			ListView_InsertColumn(UserTbl, 3, &lvc);
    
    			lvc.iSubItem = 4;
    			lvc.cx       = 150;
    			lvc.pszText  = TEXT("Drug 2");
    			ListView_InsertColumn(UserTbl, 4, &lvc);
    
    			lvc.iSubItem = 5;
    			lvc.cx       = 150;
    			lvc.pszText  = TEXT("Drug 3");
    			ListView_InsertColumn(UserTbl, 5, &lvc);
    
    			lvc.iSubItem = 6;
    			lvc.cx       = 150;
    			lvc.pszText  = TEXT("Total Symptoms");
    			ListView_InsertColumn(UserTbl, 6, &lvc);
    I know I don't have any data to put in the table because that involves alot of work(have to pull it from a database) and I don't have time tonight to mess with to get get that working but it still displays fine once I give focus to the window.

  8. #8
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    It sounds like you are painting the parent window and over-drawing the list-view. You can prevent this behaviour by using the WS_CLIPCHILDREN style when you create the parent window.

  9. #9
    Registered User
    Join Date
    Apr 2007
    Posts
    26
    Ok, I had it working but then I came up with the idea of have multiple views in my program(basically an opening screen just displaying a image, and two listViews). In order to do that with replicating ALOT of code I decided to put the three views into seperate functions.As soon as I did that(without changing the code) it broke completely. What am I doing wrong?
    There are no errors and no warnings.
    Here is my WM_PAINT message.
    Code:
    case WM_PAINT:
    		HFONT	hfont;
    
    		InvalidateRect (hWnd, NULL, TRUE) ;
    		hdc = BeginPaint(hWnd, &ps);
    
    		if(PartyLoaded == 0){
    			if(view==1){
    				hfont = EzCreateFont (hdc, TEXT("Brush Script MT"), 1500, 0, EZ_ATTR_BOLD, TRUE);
    				DisplayStart(hWnd, hdc, hfont);
    				DeleteObject (hfont);
    			}
    			else if(view==2){
    					hfont = EzCreateFont (hdc, TEXT("Brush Script MT"), 1500, 0, EZ_ATTR_BOLD, TRUE);
    					DisplayStart(hWnd, hdc, hfont);
    					DeleteObject (hfont);
    			}
    			else if(view==3){			
    					DisplayDrugs(hWnd);
    			}
    		}
    
    		else if(PartyLoaded==1){
    					if(PartyLoaded == 0){
    			if(view==1){
    				hfont = EzCreateFont (hdc, TEXT("Brush Script MT"), 1500, 0, EZ_ATTR_BOLD, TRUE);
    				DisplayStart(hWnd, hdc, hfont);
    				DeleteObject (hfont);
    			}
    			else if(view==2){
    				DisplayUsers(hWnd);
    			}
    			else if(view==3){			
    				DisplayDrugs(hWnd);
    			}
    		}
    		}
    
    		else{
    			//TODO: Add code to deal with error
    			MessageBox(hWnd, TEXT("PartyLoaded is a number other then One or Zero"), TEXT("PartyLoaded is a number other then One or Zero"), IDOK);
    		}		
    
    		EndPaint(hWnd, &ps);
    		break;
    I have attached the file that contains all the code the the views.

    If PartyLoaded is 0 then it displays nothing but the starting screen. If PartyLoaded is 1 it displays a blank screen.

    Also here is the code where I change views. The check marks work just not the actural views
    Code:
    case IDM_VIEW_STARTINGVIEW:
    			CheckMenuItem(hMenu, IDM_VIEW_USERVIEW, MF_UNCHECKED);
    			CheckMenuItem(hMenu, IDM_VIEW_DRUGVIEW, MF_UNCHECKED);
    			CheckMenuItem(hMenu, IDM_VIEW_STARTINGVIEW, MF_CHECKED);
    			view=1;
    			InvalidateRect (hWnd, NULL, TRUE) ;
    		break;
    		
    		case IDM_VIEW_USERVIEW:
    			CheckMenuItem(hMenu, IDM_VIEW_USERVIEW, MF_CHECKED);
    			CheckMenuItem(hMenu, IDM_VIEW_DRUGVIEW, MF_UNCHECKED);
    			CheckMenuItem(hMenu, IDM_VIEW_STARTINGVIEW, MF_UNCHECKED);
    			view=2;
    			InvalidateRect (hWnd, NULL, TRUE) ;
    		break;
    
    		case IDM_VIEW_DRUGVIEW:
    			CheckMenuItem(hMenu, IDM_VIEW_USERVIEW, MF_UNCHECKED);
    			CheckMenuItem(hMenu, IDM_VIEW_DRUGVIEW, MF_CHECKED);
    			CheckMenuItem(hMenu, IDM_VIEW_STARTINGVIEW, MF_UNCHECKED);
    			view=3;
    			InvalidateRect (hWnd, NULL, TRUE) ;
    		break;
    Last edited by vrek; 05-11-2007 at 12:57 PM.

  10. #10
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    WM_PAINT is called whenever the system needs the window output, not just when InvalidateRect is called. For example, if your window is obscured by another window and then brought to the front. One must expect WM_PAINT to be called many times. Therefore, creating windows inside WM_PAINT can lead to problems!

    I suggest you create a client window class to implement your startup screen. Then, in your menu handler, you can just create the appropriate window (startup window, listview1 or listview2), after destroying the current one. Or you could create the three windows in WM_CREATE and then, in your menu handler, just show the correct one using ShowWindow (and hide the others).

  11. #11
    Registered User
    Join Date
    Apr 2007
    Posts
    26
    ok, I created the windows in WM_CREATE and then used ShowWindow(UserWnd, SW_SHOWNORMAL); to display it but I am still having the same exact problems. Any other ideas of what could be wrong?

  12. #12
    Registered User
    Join Date
    Apr 2007
    Posts
    26
    I got it fixed. The problem was I was not storing the variable for the two window handles as global variables so each time I was trying to run it it was seeing the windows as un ititialized.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. IF CONDITION plese help
    By birumut in forum C Programming
    Replies: 12
    Last Post: 03-06-2009, 09:48 PM
  2. Retrieving Multiple inputs with fgets?
    By Axel in forum C Programming
    Replies: 25
    Last Post: 09-13-2005, 04:04 PM
  3. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  4. drawing boxes
    By alokin in forum C Programming
    Replies: 5
    Last Post: 04-02-2002, 10:12 PM
  5. creating label boxes
    By marco in forum C++ Programming
    Replies: 0
    Last Post: 11-27-2001, 07:06 PM