Thread: Avoiding Global variables

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    610

    Unhappy Avoiding Global variables

    I've learned at school that i should avoid Global declarations... But now with windows API i noticed all variables to be used or updated in WM_PAINT after every WM_COMMAND need to be global, otherwise won't update... Is there a limit here? and is my perception correct

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by csonx_p View Post
    I've learned at school that i should avoid Global declarations... But now with windows API i noticed all variables to be used or updated in WM_PAINT after every WM_COMMAND need to be global, otherwise won't update... Is there a limit here? and is my perception correct
    They don't need to be global - they just need to be the same variable. Local variables in a function are "recreated" every time the function is called.

    You have local variables that are static, which means that the variable remains each time.

    There are also, usually, many other ways to have local but persistent storage - the typical way is to pass something from a "never ending" function to the lower level function, which is some sort of struct that contains your actual "global" variables.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Also, dont listen too much to the 'no global variables' camp. While you should try to minimize the number you use, they are a tool to be used as necessary. One of the issues with global variables is that you can take 2 perfectly legitimate cpp files from different projects, put them into a new project and get compile errors because they happen to use the same name for a global variable. Its also kind of a pain to extern alot if you use too many global variables, but there are some times when its just too simple a solution not to use one. Like most things in life, listen to the advice of those who have gone before, but don't take it as gospel.

  4. #4
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by matsp View Post
    They don't need to be global - they just need to be the same variable. Local variables in a function are "recreated" every time the function is called.

    You have local variables that are static, which means that the variable remains each time.

    There are also, usually, many other ways to have local but persistent storage - the typical way is to pass something from a "never ending" function to the lower level function, which is some sort of struct that contains your actual "global" variables.

    --
    Mats
    Mats i declare a variable to contain a handle to an edit control inside the WinProc, initialized within WM_CREATE. But i intend to use this variable within WM_PAINT and would sometimes refresh (call InvalidateRect) WM_PAINT.. I noticed that i don't get it initialized properly unless i move its declaration globally. So you suggest i should declare it as static rather within WinProc? There are few others which would need same resolution

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Like Abachler, I don't have a religious conviction that global variables are all bad. They are, to again echo Abachler, a tool. A hammer is a tool - if you use it incorrectly your thumb, or the walls in your house, may get damaged. But use it correctly with nails, and you can build a house. A knife can kill people, but it's also a useful tool to cut up your meat or vegetables to make your dinner.

    So, used with care and for the right reasons, global variables are "OK". There are a few problems with global variables:
    1. It's hard to know when and where they get changed.
    2. There is a risk of name collisions when merging source from different places.
    3. It is harder to change the behaviour of the code if global variables are used too much - for example if you want to create another of something, it's quite easy when it's being passed around as a parameter to various functions, but if it's one global variable, you need to create another variable and then go around and change all the code that uses the first variable to KNOW which one to use at what times.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by csonx_p View Post
    Mats i declare a variable to contain a handle to an edit control inside the WinProc, initialized within WM_CREATE. But i intend to use this variable within WM_PAINT and would sometimes refresh (call InvalidateRect) WM_PAINT.. I noticed that i don't get it initialized properly unless i move its declaration globally. So you suggest i should declare it as static rather within WinProc? There are few others which would need same resolution
    And you are using C?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by Elysia View Post
    And you are using C?
    Yes, supposedly... Well my files are .cpp (whilst writing c code) cause i can't compile .c files successfully in Visual Studio 2005 standard Edition...

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by csonx_p View Post
    Yes, supposedly... Well my files are .cpp (whilst writing c code) cause i can't compile .c files successfully in Visual Studio 2005 standard Edition...
    Why not - Visual Studio (all versions, including 2008) can compile C code. Presumably you are either using C++ features, or something else is wrong in your code... What error(s) do you get?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by matsp View Post
    Why not - Visual Studio (all versions, including 2008) can compile C code. Presumably you are either using C++ features, or something else is wrong in your code... What error(s) do you get?

    --
    Mats
    I just renamed the .cpp file to .c and hit compile, I get a pre-compile header error... turning them of gives billion errors

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by csonx_p View Post
    I just renamed the .cpp file to .c and hit compile, I get a pre-compile header error... turning them of gives billion errors
    Yeah, you probably need to do a clean before you build (rebuild all or whatever it's called in MS speak), as the precompiled headers will "know" whether you are using C++ or C when compiling the header, so if you just rename the file, it will still think the precompiled header is the same [my personal opinion is that precompiled headers are only worth-wile in big projects - in small projects the saving is pretty small, really].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by matsp View Post
    Yeah, you probably need to do a clean before you build (rebuild all or whatever it's called in MS speak), as the precompiled headers will "know" whether you are using C++ or C when compiling the header, so if you just rename the file, it will still think the precompiled header is the same [my personal opinion is that precompiled headers are only worth-wile in big projects - in small projects the saving is pretty small, really].

    --
    Mats
    Visual Studio 2005 compiles well if you add a c file but as console application, once you choose windows application then is a problem.... Is there a step by step on how to compile windows application with .c files?

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by csonx_p View Post
    Visual Studio 2005 compiles well if you add a c file but as console application, once you choose windows application then is a problem.... Is there a step by step on how to compile windows application with .c files?
    It shouldn't be a problem. But seeing as I don't have MSVC (well, I have V6.0 on my machine, but I don't use it, and it would probably be quite different from 2005 anyways) here at work, I can't really help.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It really shouldn't matter. Rename it .c, then do a rebuild.
    If you get any errors, post them.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by Elysia View Post
    It really shouldn't matter. Rename it .c, then do a rebuild.
    If you get any errors, post them.
    I just copied the first few...
    Code:
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(25) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(25) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(25) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(25) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(25) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(25) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(26) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(26) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(26) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(26) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(26) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(26) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(27) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(27) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(27) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(27) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(27) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(27) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(28) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(28) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(28) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(28) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(28) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(28) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(29) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(29) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(29) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(29) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(29) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(29) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(30) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(30) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(30) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(30) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(30) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(30) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(31) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(31) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(31) : error C2143: syntax error : missing '{' before ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(31) : error C2059: syntax error : ':'
    1>c:\program files\microsoft visual studio 8\vc\include\cstdio(31) : error C2143: syntax error : missing '{' before ':'
    They all come from a file 'cstdio' .....

    my Program

    Code:
    //=============================================================================
    //FRS Range - Copyright ©2008 Songezo Nkukwana
    //=============================================================================
    
    //#include "stdafx.h"
    #include <windows.h>  //include all the basics
    #include <tchar.h>    //string and other mapping macros
    #include <string>
    #include <math.h>
    
    // Define structure for colors
    typedef struct rgbColors {
    	int R,G,B;
    } RGBColor;
    
    COLORREF g_rgbBackground = RGB(0xD3,0xD3,0xD3); // Set to grey
    
    #define MAXCOLOR 10
    
    //define an unicode string type alias
    typedef std::basic_string<TCHAR> ustring;
    
    
    // ======================================================
    // ENUM types
    
    //Edit control id's
    enum {
    	IDCE_SINGLELINE=200,
    	IDCE_SINGLELINE1,
    	IDCE_SINGLELINE2,
    	IDCE_SINGLELINE3,
    	IDCE_SINGLELINE4,
    	IDCE_SINGLELINE5,
    	IDCE_SINGLELINE6,
    	IDCE_SINGLELINE7,
    	IDCE_SINGLELINE8,
    	IDCE_SINGLELINE9,
    	IDCE_SINGLELINE10,
    	IDCE_SINGLELINE11,
    	IDCE_SINGLELINE12,
    	IDCE_SINGLELINE13,
    	IDCE_SINGLELINE14,
    	IDCE_SINGLELINE15,
    	IDCE_MULTILINE,
    	IDBC_DEFPUSHBUTTON,
    	IDBC_PUSHBUTTON,
    	IDBC_QUITBUTTON,
    	IDBC_UPDATEBUTTON,
    	IDBC_CHECKBOX_C,
    	IDBC_CHECKBOX_H,
    	IDBC_CHECKBOX_V,
    	IDBC_AUTORADIOBUTTON,
    	IDBC_GROUPBOX,
    	IDBC_ICON,
    	IDBC_BITMAP
    };
    
    // ==============================================================
    // enum constants
    
    // Radar Antenna indices
    enum {
    	AZIM,
    	ELEV,
    	GAIN,
    	RPM,
    	HGTH
    };
    
    // Radar Transmitter/Receiver indices
    enum {
    	FREQ,
    	WVLNTH,
    	PP,
    	PW,
    	PRF,
    	BNDWTH,
    	NF,
    	LOSS
    };
    
    // Target indices
    enum {
    	RCS,
    	HOT
    };
    
    // General Parameters indices
    enum {
    	FARE,
    	DP
    };
    
    //=============================================================================
    // Function declarations
    
    LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
    
    inline int ErrMsg(const ustring&);
    double GetValue(HWND hEdit,int nCtrlID);
    double Round(double dbVal, int nPlaces);
    BOOL SelectedButton(HWND hwnd, int CheckID);
    void EditBoxes(HWND hwnd, CREATESTRUCT *cs);
    BOOL SetDlgItemFloat(HWND hWnd,int nCtrlID,float fValue);
    RECT& initRecArea(int left, int top, int right, int bottom);
    void drawArea(HWND hwnd, HDC hdc, int pos, RGBColor colors[]);
    HWND OnCreate(const HWND,CREATESTRUCT*, RECT& rc, int EditID);
    void RadioButtonsText(HWND hwnd, HDC hdc, TCHAR polarLbl[]);
    void printText(HWND hWnd, TCHAR txt[], RECT& rc, HDC hDC, DWORD fnWeight);
    void paintObject(HWND hwnd, const RECT& rc, RGBColor *color, HDC hdc, int index);
    void DrawARectangle(HWND hwnd, HPEN hpen, HDC hdc, HBRUSH hbrush, const RECT& rc);
    HWND CreateEdit(const HWND,const HINSTANCE,DWORD,const RECT&,const int, const ustring&);  
    HWND CreateButton(const HWND hParent,const HINSTANCE hInst,DWORD dwStyle,const RECT& rc,
    				  const int id,const ustring& caption);
    void RadaAntennaText(HWND hwnd, TCHAR rdrAntenaLbl[5][25], TCHAR deg[], TCHAR db[], 
    					 TCHAR halfMin[], TCHAR mtrs[], HDC hdc);
    void RadarReceiverText(HWND hwnd, TCHAR rdrTrans_recv[8][20], TCHAR hz[], TCHAR mhz[], 
    					   TCHAR mtrs[], TCHAR kw[], TCHAR usec[], TCHAR db[], HDC hdc);
    
    // =============================================================================
    // Globals
    
    PAINTSTRUCT pntS;
    HWND rdrAntnCntrl[5];
    double beamWazth=0;
    int update=0,box1=0,box2=0,box3=0;
    
    // =============================================================================
    // MAIN
    int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR pStr,int nCmd)
    {
    	ustring classname=_T("RFS Range");
    	int height_frac = 250;
    	WNDCLASSEX wcx={0};  //used for storing information about the wnd 'class'
    
    	wcx.cbSize			= sizeof(WNDCLASSEX);           
    	wcx.lpfnWndProc		= WndProc;             //wnd Procedure pointer
    	wcx.hInstance		= hInst;               //app instance
    	wcx.hIcon			= (HICON)LoadImage(0,IDI_APPLICATION,IMAGE_ICON,0,0,LR_SHARED);
    	wcx.hCursor			= (HCURSOR)LoadImage(0,IDC_ARROW,IMAGE_CURSOR,0,0,LR_SHARED);
    	wcx.hbrBackground	= reinterpret_cast<HBRUSH>(COLOR_BTNFACE+1);   
    	wcx.lpszClassName	= classname.c_str(); 
    
    	if (!RegisterClassEx(&wcx))
    	{
    		ErrMsg(_T("Failed to register wnd class"));
    		return -1;
    	}
    
    	int desktopwidth=GetSystemMetrics(SM_CXSCREEN);
    	int desktopheight=GetSystemMetrics(SM_CYSCREEN);
    
    	HWND hwnd=CreateWindowEx(0,			
    		classname.c_str(),			
    		_T("RFS Range"),			
    		WS_OVERLAPPEDWINDOW,		
    		desktopwidth/4,				
    		desktopheight/4,			
    		desktopwidth/2,					
    		desktopheight/2 + height_frac,	
    		0,								
    		0,						
    		hInst,					
    		0);						
    	if (!hwnd)
    	{
    		ErrMsg(_T("Failed to create wnd"));
    		return -1;
    	}
    
    	ShowWindow(hwnd,nCmd); 
    	UpdateWindow(hwnd);
    	MSG msg;
    
    	while (GetMessage(&msg,0,0,0)>0)
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    	return static_cast<int>(msg.wParam);
    }
    
    //=============================================================================
    LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
    {
    	// ************************************************************************************
    	// Init Labels
    
    	static TCHAR deg[]="degrees", db[]="dB", halfMin[]="1/minute", mtrs[]="meters",
    		mhz[]="MHz", kw[]="kW", usec[]="usec", hz[]="Hz";
    	static TCHAR rdrAntenaLbl[5][25] = {"Beamwidth (Azimuth)  :", "Beamwidth (Elevation)  :", 
    		"Gain  :", "RPM  :", "Height  :"};
    	static TCHAR polarLbl[] = "Polarisation  :";
    	static TCHAR targetLbl[2][30] = {"Radar Cross Section (RCS) :", "Height of Target :"};
    	static TCHAR rdrTrans_recv[8][20] = {"Frequency  :", "Wavelenght  :", "Peak Power  :", "Pulse Width  :",
    		"PRF  :", "Bandwith  :", "Noise Figure  :", "Losses  :"};
    	static TCHAR genPara[2][30] = {"False Alarm Rate Exponent  :", "Detection Probability  :"};
    	
    	// ************************************************************************************
    	// Local Variables 
    
    	HDC hdc;
    //	HWND rdrAntnCntrl[5];
    	int pos=0, maxChars = 20, cnrtlIndx=0;
    	RGBColor colors[MAXCOLOR] = {{0xD3,0xD3,0xD3},{0x00,0xFF,0x00},
    	{0xFF,0xFF,0xFF},{0x00,0x00,0x00}};	
    	CREATESTRUCT *cs = reinterpret_cast<CREATESTRUCT*>(lParam);
    
    	// ************************************************************************************
    	// Window Messages
    
    	switch (uMsg)
    	{
    	case WM_CREATE:
    
    		// Create edit controls for user input
    		EditBoxes(hwnd, cs);
    
    		/* Create Radio Buttons */
    		CreateButton(hwnd,cs->hInstance,BS_AUTORADIOBUTTON,initRecArea(205,105,14,12),
    			IDBC_CHECKBOX_C,_T("Polar - C"));
    		CreateButton(hwnd,cs->hInstance,BS_AUTORADIOBUTTON,initRecArea(235,105,14,12),
    			IDBC_CHECKBOX_H,_T("Polar - H"));
    		CreateButton(hwnd,cs->hInstance,BS_AUTORADIOBUTTON,initRecArea(265,105,14,12),
    			IDBC_CHECKBOX_V,_T("Polar - V"));
    
    		/* Create Quit & Update Buttons */
    		CreateButton(hwnd,cs->hInstance,BS_DEFPUSHBUTTON,initRecArea(400,340,60,30),
    			IDBC_QUITBUTTON,_T("QUIT!"));
    		CreateButton(hwnd,cs->hInstance,BS_DEFPUSHBUTTON,initRecArea(500,340,80,30),
    			IDBC_UPDATEBUTTON,_T("UPDATE!"));
    
    		return 0;
    
    	case WM_PAINT:
    		hdc = BeginPaint(hwnd, &pntS);
    
    		/* *** User Interface *** */
    		drawArea(hwnd, hdc, pos, colors);
    		RadioButtonsText(hwnd, hdc, polarLbl);
    		RadaAntennaText(hwnd, rdrAntenaLbl, deg, db, halfMin, mtrs, hdc);
    		RadarReceiverText(hwnd, rdrTrans_recv, hz, mhz, mtrs, kw, usec, db, hdc);
    
    		/* Display beam values 
    		update ? SetDlgItemFloat(hwnd,IDCE_SINGLELINE1,(float)beamWazth) : update=0;
    				*/
    		EndPaint(hwnd, &pntS);
    		return 0;
    
    	case WM_COMMAND:
    		// Listen to the input commands
    		switch( LOWORD(wParam) )
    		{
    		case IDBC_QUITBUTTON:
    			 {
    				 if(HIWORD(wParam) == BN_CLICKED){
    					 PostQuitMessage(0);
    				 }
    			 }
    		case IDBC_UPDATEBUTTON:
    			 {
    				 if(HIWORD(wParam) == BN_CLICKED)
    				 {
    					 InvalidateRect (hwnd, NULL, TRUE);
    					 UpdateWindow(hwnd);
    				 }
    			 }
    		}
    		return 0;
    
    	case WM_TIMER: 
    		//SetTimer(hwnd, ID_TIMER, 500, NULL);
    		break;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);    
    		return 0;
    	default:
    		//let system deal with msg
    		return DefWindowProc(hwnd,uMsg,wParam,lParam);  
    	}
    	return 0;
    }
    
    //=============================================================================
    inline int ErrMsg(const ustring& s)
    {
    	return MessageBox(0,s.c_str(),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);
    }
    
    //=============================================================================
    // EDIT control
    HWND CreateEdit(const HWND hParent,const HINSTANCE hInst,DWORD dwStyle,
    				const RECT& rc,const int id,const ustring& caption)
    {
    	dwStyle|=WS_CHILD|WS_VISIBLE;
    	return CreateWindowEx(WS_EX_CLIENTEDGE,
    		_T("edit"),							
    		caption.c_str(),					
    		dwStyle,							
    		rc.left,							
    		rc.top,								
    		rc.right,						
    		rc.bottom,							
    		hParent,							
    		reinterpret_cast<HMENU>(static_cast<INT_PTR>(id)),
    		hInst,								
    		0);									
    }
    //=============================================================================
    // BUTTON Control
    HWND CreateButton(const HWND hParent,const HINSTANCE hInst,DWORD dwStyle,
    				  const RECT& rc,const int id,const ustring& caption)
    {
    	dwStyle|=WS_CHILD|WS_VISIBLE;
    	return CreateWindowEx(0,         
    		_T("button"),               
    		caption.c_str(),            
    		dwStyle,                    
    		rc.left,                     
    		rc.top,                      
    		rc.right,                     
    		rc.bottom,                    
    		hParent,                      
    		reinterpret_cast<HMENU>(static_cast<INT_PTR>(id)),
    		hInst,                        
    		0);                        
    }
    
    // Purpose: Draws an object on the window
    void paintObject(HWND hwnd, const RECT& rc, RGBColor *color, HDC hdc, int index)
    {					
    	HPEN hpen = CreatePen(PS_SOLID, 2, RGB(color[index+3].R, color[index+3].G, color[index+3].B));
    	HBRUSH hbrush = CreateSolidBrush(RGB(color[index].R, color[index].G, color[index].B));
    	DrawARectangle(hwnd, hpen, hdc, hbrush, rc);
    	DeleteObject(hpen);
    	DeleteObject(hbrush);
    }
    
    // Purpose: Draws a rectangle which will have text boxes for input data
    void DrawARectangle(HWND hwnd, HPEN hpen, HDC hdc, HBRUSH hbrush, const RECT& rc) 
    {
    	// Select the new pen and brush, and then draw.
    	HPEN hpenOld = (HPEN)SelectObject(hdc, hpen);
    	HBRUSH hbrushOld = (HBRUSH)SelectObject(hdc, hbrush);
    	Rectangle(hdc,rc.left,rc.top,rc.right,rc.bottom);
    	SelectObject(hdc, hpenOld);
    	SelectObject(hdc, hbrushOld);
    }
    
    // Initialize rectangle area
    RECT& initRecArea(int left, int top, int right, int bottom)
    {
    	static RECT rec;
    
    	rec.left=left;
    	rec.top=top;
    	rec.right=right;
    	rec.bottom=bottom;
    
    	return rec;
    }
    
    //handles the WM_CREATE message of the main, parent window; return -1 to fail
    HWND OnCreate(const HWND hwnd,CREATESTRUCT *cs, RECT& rc, int EditID)
    {
    	return CreateEdit(hwnd,cs->hInstance,0,rc,EditID,_T(""));
    }
    
    // Display text on screen
    void printText(HWND hWnd, TCHAR txt[], RECT& rc, HDC hDC, DWORD fnWeight)
    {
    	long lfHeight = -MulDiv(12, GetDeviceCaps(hDC, LOGPIXELSY), 72);
    	HFONT font = CreateFont(lfHeight, 0, 0, 0, fnWeight, FALSE, 
    		0, 0, 0, 0, 0, 0, 0, _T("Times New Roman"));
    
    	HGDIOBJ hDefFont = SelectObject(hDC, font);
    	
    	SetBkColor(hDC, g_rgbBackground);
    	TextOut(hDC, rc.left, rc.top, txt, (int)_tcslen(txt));
    
    	SelectObject(hDC, hDefFont);
    	DeleteObject(hDefFont);
    } 
    
    // Read in text as values
    double GetValue(HWND hEdit,int nCtrlID)
    {
    	float fValue = 0.00;
    	char szText[256];
    
    	GetWindowText(hEdit, szText, nCtrlID);
    	sscanf(szText,"%f",&fValue);
    	return Round((double)fValue, 2);
    }
    
    // Display the read value to screen
    BOOL SetDlgItemFloat(HWND hWnd,int nCtrlID,float fValue)
    {
    	HWND hControl = GetDlgItem(hWnd,nCtrlID);
    	char szText[256];
    	sprintf(szText,"%.2f",fValue);			
    	return SetWindowTextA(hControl,szText);
    }
    
    // rounds a double variable to nPlaces decimal places
    double Round(double dbVal, int nPlaces)
    {
        const double dbShift = pow(10.0, nPlaces);
        return  floor(dbVal * dbShift + 0.5) / dbShift; 
    }
    
    // Check if Radio button is checked
    BOOL SelectedButton(HWND hwnd, int CheckID)
    {
    	return (int)SendMessage ( GetDlgItem(hwnd,CheckID),BM_GETCHECK,0,0 );
    }
    
    // ======================================================================================================
    // User Interface functions
    
    /* Labes for Radar Antenna Area */
    void RadaAntennaText(HWND hwnd, TCHAR rdrAntenaLbl[5][25], TCHAR deg[], TCHAR db[],
    					 TCHAR halfMin[], TCHAR mtrs[], HDC hdc)
    {
    	printText(hwnd, _T("Radar Antenna"), initRecArea(15,15,0,0), hdc, 700); // Header
    
    	printText(hwnd, rdrAntenaLbl[AZIM], initRecArea(55,45,0,0), hdc, 0);
    	printText(hwnd, deg, initRecArea(265,45,0,0), hdc, 0);
    	printText(hwnd, rdrAntenaLbl[ELEV], initRecArea(48,75,0,0), hdc, 0);
    	printText(hwnd, deg, initRecArea(265,75,0,0), hdc, 0);
    	printText(hwnd, rdrAntenaLbl[GAIN], initRecArea(156,130,0,0), hdc, 0);
    	printText(hwnd, db, initRecArea(265,130,0,0), hdc, 0);
    	printText(hwnd, rdrAntenaLbl[RPM], initRecArea(151,160,0,0), hdc, 0);
    	printText(hwnd, halfMin, initRecArea(265,160,0,0), hdc, 0);
    	printText(hwnd, rdrAntenaLbl[HGTH], initRecArea(145,190,0,0), hdc, 0);
    	printText(hwnd, mtrs, initRecArea(265,190,0,0), hdc, 0);
    }
    			     
    /* Labes for Radar Transceiver Area */
    void RadarReceiverText(HWND hwnd, TCHAR rdrTrans_recv[8][20], TCHAR hz[], TCHAR mhz[], 
    					   TCHAR mtrs[], TCHAR kw[], TCHAR usec[], TCHAR db[], HDC hdc)
    {
    	/* Radar Transmitter/Receiver Area */
    	printText(hwnd, _T("Radar Transmitter/Receiver"), 
    		initRecArea(350,15,0,0), hdc, 700); // Header
    
    	printText(hwnd, rdrTrans_recv[FREQ], initRecArea(395,45,0,0), hdc, 0);
    	printText(hwnd, mhz, initRecArea(540,45,0,0), hdc, 0);
    	printText(hwnd, rdrTrans_recv[WVLNTH], initRecArea(388,75,0,0), hdc, 0);
    	printText(hwnd, mtrs, initRecArea(540,75,0,0), hdc, 0);
    	printText(hwnd, rdrTrans_recv[PP], initRecArea(384,105,0,0), hdc, 0);
    	printText(hwnd, kw, initRecArea(540,105,0,0), hdc, 0);
    	printText(hwnd, rdrTrans_recv[PW], initRecArea(386,135,0,0), hdc, 0);
    	printText(hwnd, usec, initRecArea(540,135,0,0), hdc, 0);
    	printText(hwnd, rdrTrans_recv[PRF], initRecArea(431,165,0,0), hdc, 0);
    	printText(hwnd, hz, initRecArea(540,165,0,0), hdc, 0);
    	printText(hwnd, rdrTrans_recv[BNDWTH], initRecArea(401,195,0,0), hdc, 0);
    	printText(hwnd, mhz, initRecArea(540,195,0,0), hdc, 0);
    	printText(hwnd, rdrTrans_recv[NF], initRecArea(380,225,0,0), hdc, 0);
    	printText(hwnd, db, initRecArea(540,225,0,0), hdc, 0);
    	printText(hwnd, rdrTrans_recv[LOSS], initRecArea(415,255,0,0), hdc, 0);
    	printText(hwnd, db, initRecArea(540,255,0,0), hdc, 0);
    }
    
    // Display text around radio buttons
    void RadioButtonsText(HWND hwnd, HDC hdc, TCHAR polarLbl[])
    {
    	printText(hwnd, polarLbl, initRecArea(115,100,0,0), hdc, 0);
    	printText(hwnd, _T("c"), initRecArea(222,100,0,0), hdc, 0); 
    	printText(hwnd, _T("h"), initRecArea(252,100,0,0), hdc, 0);
    	printText(hwnd, _T("v"), initRecArea(282,100,0,0), hdc, 0);
    }
    
    // Draw Rectangles on Window Area
    void drawArea(HWND hwnd, HDC hdc, int pos, RGBColor colors[])
    {
    	paintObject(hwnd,initRecArea(10,10,340,230),colors, hdc, pos);
    	paintObject(hwnd,initRecArea(345,10,625,285),colors, hdc, pos);
    	paintObject(hwnd,initRecArea(10,235,340,335),colors, hdc, pos);
    	paintObject(hwnd,initRecArea(10,340,340,440),colors, hdc, pos);
    	paintObject(hwnd,initRecArea(10,445,625,720),colors, hdc, pos);
    }
    
    // Isert Edit Controls
    void EditBoxes(HWND hwnd, CREATESTRUCT *cs)
    {
    	/* RADAR ANTENNA - Edit Boxes */
    	OnCreate(hwnd,cs,initRecArea(205,45,55,20),IDCE_SINGLELINE);
    	OnCreate(hwnd,cs,initRecArea(205,75,55,20),IDCE_SINGLELINE1);
    	OnCreate(hwnd,cs,initRecArea(205,130,55,20),IDCE_SINGLELINE2);
    	OnCreate(hwnd,cs,initRecArea(205,160,55,20),IDCE_SINGLELINE3);
    	OnCreate(hwnd,cs,initRecArea(205,190,55,20),IDCE_SINGLELINE4);
    
    	/* RADAR TRANSMITTER/RECEIVER - Edit Boxes */
    	OnCreate(hwnd,cs,initRecArea(480,45,55,20),IDCE_SINGLELINE5);
    	OnCreate(hwnd,cs,initRecArea(480,105,55,20),IDCE_SINGLELINE7);
    	OnCreate(hwnd,cs,initRecArea(480,135,55,20),IDCE_SINGLELINE8);
    	OnCreate(hwnd,cs,initRecArea(480,165,55,20),IDCE_SINGLELINE9);
    	OnCreate(hwnd,cs,initRecArea(480,195,55,20),IDCE_SINGLELINE10);
    	OnCreate(hwnd,cs,initRecArea(480,225,55,20),IDCE_SINGLELINE11);
    	OnCreate(hwnd,cs,initRecArea(480,255,55,20),IDCE_SINGLELINE12);
    
    	/* TARGET - Edit Boxes */
    	OnCreate(hwnd,cs,initRecArea(205,270,55,20),IDCE_SINGLELINE13);
    	OnCreate(hwnd,cs,initRecArea(205,300,55,20),IDCE_SINGLELINE14);
    }

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    cstdio is C++, not C.
    C uses stdio.h.

    Are you writing C or C++? You seem to have a mix.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 08-06-2008, 09:59 AM
  2. global variables
    By shadovv in forum C++ Programming
    Replies: 7
    Last Post: 10-24-2005, 02:21 PM
  3. global variables - okay sometimes...?
    By MadHatter in forum C++ Programming
    Replies: 21
    Last Post: 01-21-2003, 04:23 PM
  4. global variables
    By rdnjr in forum Linux Programming
    Replies: 0
    Last Post: 01-07-2003, 10:28 AM
  5. Global variables? Bad! Yes, but to what extent?
    By Boksha in forum C++ Programming
    Replies: 6
    Last Post: 05-26-2002, 04:37 PM