Thread: x.h header file

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    932

    x.h header file

    Why cant i put this in a header file?

    error C2143: syntax error : missing ';' before '.'
    error C4430: missing type specifier - int assumed.
    error C2371: 'rect' : redefinition; different basic types

    Code:
    RECT rect ;  
        rect.left   = 15 ;
        rect.top    = 15 ;
        rect.right  = 235 ;
        rect.bottom = 125 ;
    Using Windows 10 with Code Blocks and MingW.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Put your assignments inside a function body.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Declarations and definitions can appear outside functions. Code cannot.
    You should not define or declare variables in headers, either.
    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.

  4. #4
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Code:
    RECT rect = {15,15,235,125};  
    //    rect.left   = 15 ;
    //    rect.top    = 15 ;
    //    rect.right  = 235 ;
    //    rect.bottom = 125 ;

  5. #5
    Registered User
    Join Date
    Dec 2007
    Posts
    932
    Salem, Elysia, Bob, thank you.

    Bob's version is working.
    Using Windows 10 with Code Blocks and MingW.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, it's called initialization. Initialization can be done outside functions, but assignments cannot.
    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
    Dec 2007
    Posts
    932
    Ive been trying to solve this all week, still i cant see the reason why.

    If i put the variables in the .cpp file it works fine.

    If i put the variables in the .h file, outside the function, it only draws the first rectangle.

    If i put the variables in the .h file, inside the function, it doesnt draw anything at all.
    Code:
    #include <windows.h>
    #include "variables.h"
    #define ID_TIMER  101
    
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
        static TCHAR szAppName[] = TEXT ("Invalidaterect") ;
        HWND hwnd ;
        MSG msg ;
        WNDCLASS wndclass ;
        wndclass.style = CS_HREDRAW | CS_VREDRAW ;
        wndclass.lpfnWndProc = WndProc ;
        wndclass.cbClsExtra = 0 ;
        wndclass.cbWndExtra = 0 ;
        wndclass.hInstance = hInstance ;
        wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
        wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
        wndclass.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH) ;
        wndclass.lpszMenuName = NULL ;
        wndclass.lpszClassName = szAppName ;
        if (!RegisterClass (&wndclass))
        {
            return 0 ;
        }
        hwnd = CreateWindow (szAppName, // window class name
               TEXT ("The Hello Program"), // window caption
               WS_OVERLAPPEDWINDOW, // window style
               CW_USEDEFAULT, // initial x position
               CW_USEDEFAULT, // initial y position
               CW_USEDEFAULT, // initial x size
               CW_USEDEFAULT, // initial y size
               NULL, // parent window handle
               NULL, // window menu handle
               hInstance, // program instance handle
               NULL) ; // creation parameters
    
        ShowWindow (hwnd, iCmdShow) ;
        UpdateWindow (hwnd) ;
    
        while (GetMessage (&msg, NULL, 0, 0))
        {
            TranslateMessage (&msg) ;
            DispatchMessage (&msg) ;
        }
        return msg.wParam ;
    }
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    
    
        switch (message)
        {   
    	case WM_SIZE:
                 cxClient = LOWORD (lParam) ;
                 cyClient = HIWORD (lParam) ;
                 return 0 ;
            case WM_CREATE:
                 SetTimer (hwnd, ID_TIMER, 1000, NULL);
                 break;
            case WM_TIMER :
                 bFlipFlop = !bFlipFlop ;        
                 InvalidateRect (hwnd, &rect1, FALSE) ;
    	     InvalidateRect (hwnd, &rect2, FALSE) ;
    	     InvalidateRect (hwnd, &rect3, FALSE) ;
    	     InvalidateRect (hwnd, &rect4, FALSE) ;
                 return 0 ;
            case WM_PAINT:
                 hdc = BeginPaint(hwnd, &ps);
                 paint();
                 EndPaint(hwnd, &ps);
                 return 0 ;
            case WM_DESTROY:
                 KillTimer (hwnd, ID_TIMER) ;
                 PostQuitMessage (0) ; 
                 return 0 ;
        }
        return DefWindowProc (hwnd, message, wParam, lParam) ;
    }
    Code:
    //variables.h
    
    static BOOL bFlipFlop = FALSE ;
    HDC hdc ;
    PAINTSTRUCT ps ;
    HBRUSH hBrush ;
    static int cxClient, cyClient ;
    
    //RECT rect1,rect2,rect3,rect4;
    
    RECT rect1   = {15,15,235,125} ;
    POINT arrow1 [7] = {{20, 50},{180, 50},{180, 20},{230, 70},
                                      {180, 120},{180, 90},{20, 90}} ;
    
    RECT rect2  = {cxClient -235, 15, cxClient -15, 125} ;
    POINT arrow2 [7] = {{cxClient -230, 70},{cxClient -170, 20},{cxClient -170, 50},{cxClient -25, 50},
                                      {cxClient -25, 90},{cxClient -170, 90},{cxClient -170, 120}} ;
    
    RECT rect3  = {15, cyClient -125, 235, cyClient -15} ;
    POINT arrow3 [7] = {{20, cyClient -90},{180, cyClient-90},{180, cyClient-120},
                                    {230, cyClient-70},{180, cyClient-20},
                                    {180, cyClient-50},{20, cyClient-50}} ;
    
    RECT rect4  = {cxClient -235, cyClient -125, cxClient -15, cyClient -15} ;
    POINT arrow4 [7] = {{cxClient -230, cyClient -70},{cxClient -170, cyClient -120},
                                    {cxClient -170, cyClient -90}, {cxClient -25, cyClient -90},
                                    {cxClient -25, cyClient -50},   {cxClient -170, cyClient -50},
                                    {cxClient -170, cyClient -20}} ;
    
    void paint()
    {
    
                 //rectangles
                 hBrush = CreateSolidBrush (bFlipFlop ?  RGB(255,0,0)     : RGB(0,0,255)) ;
                 FillRect (hdc, &rect1, hBrush) ;
    	     hBrush = CreateSolidBrush (bFlipFlop ?  RGB(0,0,255)     : RGB(255,0,0)) ;
    	     FillRect (hdc, &rect2, hBrush) ;
    	     hBrush = CreateSolidBrush (bFlipFlop ?  RGB(0,0,255)     : RGB(255,0,0)) ;
    	     FillRect (hdc, &rect3, hBrush) ;
    	     hBrush = CreateSolidBrush (bFlipFlop ?  RGB(255,0,0)     : RGB(0,0,255)) ;
    	     FillRect (hdc, &rect4, hBrush) ;
                
                 //arrows
                 hBrush  = CreateSolidBrush (bFlipFlop ? RGB(0,0,255)     : RGB(255,0,0)) ;
                 SelectObject(hdc, hBrush);
                 Polygon(hdc, arrow1, 7); 
    	     hBrush  = CreateSolidBrush (bFlipFlop ? RGB(255,0,0)     : RGB(0,0,255)) ;
                 SelectObject(hdc, hBrush);
                 Polygon(hdc, arrow2, 7);
                 hBrush  = CreateSolidBrush (bFlipFlop ? RGB(255,0,0)     : RGB(0,0,255)) ;
                 SelectObject(hdc, hBrush);
    	     Polygon(hdc, arrow3, 7);
    	     hBrush  = CreateSolidBrush (bFlipFlop ? RGB(0,0,255)     : RGB(255,0,0)) ;
                 SelectObject(hdc, hBrush);
    	     Polygon(hdc, arrow4, 7);
                 DeleteObject (hBrush) ;
    }
    Last edited by Ducky; 11-01-2008 at 03:44 AM.
    Using Windows 10 with Code Blocks and MingW.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I personally would put all of the stuff in "variables.h" into a .c or .cpp file (which of those two you choose depends on whether the rest of the project is C or C++). Then you need to put a prototype for paint() into your variables.h (which probably shouldn't have that name, but whatever...)

    As to why you are not drawing, I'm fairly confident that you are expecting something different from what you are actually doing. There are several of your initializations that appear to be incorrect - this is the first one:
    Code:
    RECT rect2  = {cxClient -235, 15, cxClient -15, 125} ;
    Now, cxclient is zero when this initialization is done, since your code hasn't started executing properly when the initialization is done (so, what I'm trying to say is that it happens before WinMain - eitner at compile time or as part of the runtime startup, which of those it is doesn't really make much difference, but I presume you are not actually wanting rect2 to have -235, 15, -15, 125 in it, as that would be outside of the visible aree). So when you do InvalidateRect(&rect2), it doesn't invalidate any area of the screen. Likewise when you draw the polygons, they are outside the screen (negative numbers).

    To fix this, you will need to reset your rectangles and arrow values for every WM_SIZE message. I can think of two solutions,
    1. Put the values for rect and arrow as constant values, with negative values to indicate that the value should be subtracted from X or Y, and then have two functions, one for rect and one for a list of points, that does the calculation for you (the function should also takes cxclient, cyclient as a parmeter).
    2. Have the rect/arrow initializations inside the paint function, and pass cxclient, cyclient to the function (and while you are at it, pass hdc as a parameter as well).

    I prefer the first solution, because it is more generic.

    Have you actually set up a timer somewhere in your code? I don't see anything that does it [not that it matters right now].

    --
    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
    Dec 2007
    Posts
    932
    Thank you Mats for taking the time to help me.

    *me tapping on my forehead*
    Of course they are initialized before calling WM_SIZE so they are 0.


    I did what you explained in the first version and its not working which is normal because when the InvalidateRect calls get called there is nothing to invalidate.
    So if i have to initialize the values in WndProc and in the functions also thats not really a space saver solution i guess.
    The best would be if i could call variables.h in WndProc. I dont know if its possible.
    Or maybe call a function in WM_TIMER just before InvalidateRect that does nothing only initializes variables.

    Then you need to put a prototype for paint() into your variables.h
    Well the reason for using a header file is to save place in the .cpp file.
    So now one line less or more is not really gonna save me any place either, is it?

    Have you actually set up a timer somewhere in your code?
    Yes of course its SetTimer() in WM_CREATE.

    PS i never thought a small program would cause so much trouble.
    Last edited by Ducky; 11-01-2008 at 10:11 AM.
    Using Windows 10 with Code Blocks and MingW.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Ducky View Post
    Well the reason for using a header file is to save place in the .cpp file.
    So now one line less or more is not really gonna save me any place either, is it?
    It is not about saving space - it is about doing things correct and saving you troubles and issues.
    They do not need to be put inside the same .cpp file as the rest of the code. You can place it in a .cpp file of its own. Just remember to create a prototype for paint and put it inside a header and include it in the .cpp file that calls the function.
    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.

  11. #11
    Registered User
    Join Date
    Dec 2007
    Posts
    932
    I gotta recheck my protoype knowledge then.

    I thought they were to tell WinMain about a function defined later after WinMain in the program.
    But since the function is declared in the header file and the header file called "included" in the
    beginning of the program i thought you didnt need to declare any prototypes.

    Thank you Elysia. Where would we be without you!
    Using Windows 10 with Code Blocks and MingW.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Ducky View Post
    I thought they were to tell WinMain about a function defined later after WinMain in the program.
    But since the function is declared in the header file and the header file called "included" in the
    beginning of the program i thought you didnt need to declare any prototypes.
    Well, theoretically, you are right.
    But the problem is that we typically do not define functions in headers (and if we do, we mark them with "inline"), because when working with multiple files, when you include that header in both files, you will get a multiple symbols error from the linker!

    So functions are usually put in .cpp files, a prototype is created in a header file.
    To call functions, the compiler needs to see a declaration of the function you wish to call (remember that a definition is also a declaration). Therefore, to call a function in another file, you need a prototype.
    You can call functions that appears earlier in your code from a function later in the code (in the same file) since it would be defined, but prototypes are still considered good practice!
    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. Need Help Fixing My C Program. Deals with File I/O
    By Matus in forum C Programming
    Replies: 7
    Last Post: 04-29-2008, 07:51 PM
  2. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  3. Making a LIB file from a DEF file for a DLL
    By JMPACS in forum C++ Programming
    Replies: 0
    Last Post: 08-02-2003, 08:19 PM
  4. Replies: 6
    Last Post: 04-02-2002, 05:46 AM