CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Feb 2012
    Posts
    19

    Make HWND global LNK2005

    hey folks,

    im codin a win32 app. and i want to make the HWND hWnd to a global variable. well i put all this gui stuff in a file GUI.h and GUI.cpp. now i want to make the window handle global so i can acces it if i include the header. Now my GUI.h looks like that:

    but if i do i get the error :

    Fehler 5 error LNK2005: "struct HWND__ * MyWindowHandle" (?MyWindowHandle@@3PAUHWND__@@A) ist bereits in GUI.obj definiert.
    [already defined in GUI.obj]

    What am i doing wrong?

    GUI.h
    Code:
    #include "Windows.h"
    
    #ifndef _GUI
    #define _GUI
    
    HWND WindowHandle;
    int initGUI(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpcmdline, int ncmdshow);
    
    #endif //_GUI
    
    #endif //_GUI
    Main.cpp
    Code:
    #include "Windows.h"
    #include "GUI.h"
    
    //==============================================================================
    int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpcmdline, int ncmdshow)
    //==============================================================================
    {
      return initGUI(hInst, hPrevInst, lpcmdline, ncmdshow);
    } // WinMain
    GUI.cpp
    Code:
    #include "GUI.h"
    #include "Commctrl.h"
    #include "Tchar.h"
    #include "time.h"
    #include <vector>
    using std::vector;
    #include "TableManager.h"
    #include "resource.h"
    
    #pragma comment(lib, "comctl32.lib")
    
    //_____________________________________________________________________________
    //  DEFINES
    #define TMR_0_ID 01
    #define LBX_0_ID 10
    #define BTN_0_ID 20
    #define BTN_1_ID 21
    #define DTP_0_ID 30
    #define DTP_1_ID 31
    #define STB_0_ID 40
    
    //_____________________________________________________________________________
    //  Variables
    static wchar_t AppTitle[] = L"THB";  // The string that appears in the application's title bar.
    static tm sysTime;
    static HWND hLBX;
    static HWND hBTN[2];
    static HWND hDTP[2];
    static HWND hSTB;
    static HFONT font;
    static TABLEMANAGER TableManager;
    static bool AutoplayerStatus = 0;
    
    //_____________________________________________________________________________
    //  Prototypes
      LRESULT CALLBACK WindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
      void Heartbeat(HWND hWnd);
      void GUI_onCreate(HWND hWnd);
      void GUI_onClose(HWND hWnd);
      void GUI_Update(HWND hWnd);
      void GUI_StopAP(HWND hWnd);
      void GUI_StartAP(HWND hWnd);
      void InstanciateAllSingletons();
    
    //==============================================================================
    int initGUI(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpcmdline, int ncmdshow)
    {
      MSG message;
      HWND hWnd;
      WNDCLASSEX windowclass; 
      INITCOMMONCONTROLSEX icex;
    
      // Struktur für Fenstereigenschaften
      windowclass.cbSize = sizeof (WNDCLASSEX);
      windowclass.style = CS_HREDRAW | CS_VREDRAW;
      windowclass.lpfnWndProc = WindowProc;
      windowclass.cbClsExtra = 0;
      windowclass.cbWndExtra = 0;
      windowclass.hInstance = hInst;
      windowclass.hIcon  = LoadIcon (hInst, MAKEINTRESOURCE(IDI_ICON1));
      windowclass.hIconSm = LoadIcon (hInst, MAKEINTRESOURCE(IDI_ICON1));
      windowclass.hCursor = LoadCursor (NULL, IDC_ARROW);
      windowclass.hbrBackground = (HBRUSH)COLOR_BACKGROUND+1;
      windowclass.lpszMenuName = NULL; //(LPCWSTR)("Datei");
      windowclass.lpszClassName = AppTitle;
    
      // Fensterklasse registrieren
      if (!RegisterClassEx (&windowclass) ){
            MessageBox(NULL, _T("Call to RegisterClassEx failed!"), AppTitle, NULL);
            return 1;
      }
      
    
       icex.dwSize = sizeof(icex);
       icex.dwICC = ICC_DATE_CLASSES;
       InitCommonControlsEx(&icex);
    
      // Fenster-Handle erzeugen
      hWnd = CreateWindowEx (
        NULL,//WS_EX_TOOLWINDOW,
        AppTitle,
        AppTitle,
        WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX,
        CW_USEDEFAULT, CW_USEDEFAULT,
        406, 328,
        NULL,
        NULL,
        hInst,
        NULL);
      
      // Test Create();
      if (!hWnd){
            MessageBox(NULL,_T("Call to CreateWindow failed!"), AppTitle, NULL);
            return 1;
      }
    
      ShowWindow(hWnd, SW_SHOWNORMAL);
      UpdateWindow(hWnd);
      
      // Empfange Nachrichten
      while (GetMessage(&message, NULL, 0, 0) ){
        TranslateMessage (&message);
        DispatchMessage (&message);
      }
      return (int)(message.wParam);
    } // WinMain
    //==============================================================================
    void GUI_onCreate(HWND hWnd){
    
      // Create Forms
      HINSTANCE hInst = GetModuleHandle(NULL);
      hLBX    = CreateWindow(L"LISTBOX",L"TableListView",WS_VISIBLE|WS_CHILD|LBS_NOINTEGRALHEIGHT|LBS_NOTIFY|WS_VSCROLL|WS_BORDER|LBS_NOSEL,0,   0, 200, 200,hWnd, (HMENU)LBX_0_ID, hInst, NULL);
      hBTN[0] = CreateWindow(L"BUTTON",L"AP",                  WS_CHILD|WS_VISIBLE | BS_CHECKBOX | BS_PUSHLIKE, 200, 0,  40, 40, hWnd, (HMENU)BTN_0_ID, hInst, NULL);
      hBTN[1] = CreateWindow(L"BUTTON",L"Pref",                   BS_PUSHBUTTON|WS_CHILD|WS_VISIBLE,            200, 40, 40, 40, hWnd, (HMENU)BTN_1_ID, hInst, NULL);
      hDTP[0] = CreateWindow(DATETIMEPICK_CLASS,TEXT("StartTime"),WS_BORDER|WS_CHILD|WS_VISIBLE|DTS_TIMEFORMAT, 200, 80, 70, 25, hWnd, (HMENU)DTP_0_ID, hInst, NULL);
      hDTP[1] = CreateWindow(DATETIMEPICK_CLASS,TEXT("StopTime"), WS_BORDER|WS_CHILD|WS_VISIBLE|DTS_TIMEFORMAT, 270, 80, 70, 25, hWnd, (HMENU)DTP_1_ID, hInst, NULL);
      hSTB    = CreateWindow(STATUSCLASSNAME, NULL,               WS_CHILD| WS_VISIBLE,                         0,0,0,0,         hWnd, (HMENU)STB_0_ID, hInst, NULL);
    
      // Change preferences
      DateTime_SetFormat(hDTP[0],L"HH':'mm");
      DateTime_SetFormat(hDTP[1],L"HH':'mm");
    
      // Tell the status bar to create the window parts.
      int edges[4] = {40,80,350,-1};
      SendMessage(hSTB, SB_SETPARTS, (WPARAM) 4, (LPARAM)edges);
    
      InstanciateAllSingletons();
    
      // Load the Tablemap
      p_Tablemap->LoadTablemap(BWIN_TABLEMAP_FILENAME);
    
      GUI_Update(hWnd);
    
      // Create timer for tablemanager     
      if(!SetTimer(hWnd, TMR_0_ID, 1000, NULL))
        MessageBox(NULL, _T("No timer available"), AppTitle, MB_ICONINFORMATION);
    }
    //==============================================================================
    void GUI_onClose(HWND hWnd){
    //==============================================================================
      if(AutoplayerStatus && !TableManager.countOpenTables())
        MessageBox(NULL, _T("AP is still seated."), AppTitle, NULL);
      else{
        KillTimer(hWnd, TMR_0_ID);
        PostQuitMessage (0);
      }
    }
    //==============================================================================
    void GUI_Update(HWND hWnd){
    //==============================================================================
      // Update Time
      time_t rawtime = time(NULL);
      localtime_s(&sysTime, &rawtime );
    
      // Update listbox
      TableManager.UpdateListBox(hLBX);
    
      //Update statusbar
      const int l = 15;
      wchar_t s[l];
      memset(s,0,sizeof(wchar_t)*l);
      swprintf(s,L"NL %d",LIMIT);
      SendMessage(hSTB, SB_SETTEXT, (SBT_NOBORDERS<<8)|0, (LPARAM)s);
      memset(s,0,sizeof(wchar_t)*l);
      swprintf(s,L"%0d/%0d", TableManager.countOpenTables(), MAXTABLES);
      SendMessage(hSTB, SB_SETTEXT, (SBT_NOBORDERS<<8)|1, (LPARAM)s);
      memset(s,0,sizeof(wchar_t)*l);
      swprintf(s,L"AP: %s", AutoplayerStatus ? L"AN" : L"AUS");
      SendMessage(hSTB, SB_SETTEXT, (SBT_NOBORDERS<<8)|2, (LPARAM)s);
      memset(s,0,sizeof(wchar_t)*l);
      swprintf(s,L"%0d:%0d", sysTime.tm_hour, sysTime.tm_min);
      SendMessage(hSTB, SB_SETTEXT, (SBT_NOBORDERS<<8)|3, (LPARAM)s);
    }
    //==============================================================================
    void GUI_StartAP(HWND hWnd){
    //==============================================================================
      AutoplayerStatus = 1;
      SendMessage(hBTN[0], BM_SETCHECK, BST_CHECKED, NULL);
    }
    //==============================================================================
    void GUI_StopAP(HWND hWnd){
    //==============================================================================
      AutoplayerStatus = 0;
      SendMessage(hBTN[0], BM_SETCHECK, BST_UNCHECKED, NULL);
    }
    //==============================================================================
    void Heartbeat(HWND hWnd){
      TableManager.Update();
      GUI_Update(hWnd);
    }
    //==============================================================================
    void InstanciateAllSingletons(){
      if (!p_Tablemap) p_Tablemap = new TABLEMAP;
     // if (!p_Scraper) p_Scraper = new SCRAPER;
    }
    //==============================================================================
    LRESULT CALLBACK WindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    //==============================================================================
    {
      switch (message){
        //-------------------------------------------------------------------------
        case WM_CREATE:{
          GUI_onCreate(hWnd);  
          return (0);
        }
        //-------------------------------------------------------------------------
        case WM_CLOSE:{
          GUI_onClose(hWnd);
          return (0);
        }
        //-------------------------------------------------------------------------
        case WM_TIMER:{
          switch (wParam){
            case TMR_0_ID:
              Heartbeat(hWnd);
              return 0;
            default:return 0;
          }
        }
        //-------------------------------------------------------------------------
        case WM_COMMAND:{
          switch (LOWORD(wParam)){
            case BTN_0_ID:
              if(AutoplayerStatus)
                GUI_StopAP(hWnd);
              else
                GUI_StartAP(hWnd);
                return (0);
            case BTN_1_ID:
              return (0);
            default:return 0;
          }
        }
        //-------------------------------------------------------------------------
        case WM_KEYDOWN:{
          switch (wParam){
            case VK_ESCAPE:
              PostQuitMessage (0);
              return (0);
            case 0x31:
              return (0);
            case 0x32:
              return (0);
            case VK_LEFT:
              return (0);
            default:return 0;
          }
        //-------------------------------------------------------------------------
        }
      }
      return (DefWindowProc (hWnd, message, wParam, lParam) );
    } // WindowProc

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Make HWND global LNK2005

    Quote Originally Posted by ImNotaBot View Post
    hey folks,

    im codin a win32 app. and i want to make the HWND hWnd to a global variable. well i put all this gui stuff in a file GUI.h and GUI.cpp. now i want to make the window handle global so i can acces it if i include the header. Now my GUI.h looks like that:
    When you use an include file, all you're doing is taking the text from the include file and placing it into your source file. Nothing more than that. So what does GUI.CPP and Main.cpp end up with?

    You now have a declaration of MyWindowHandle in two modules. Now when the linker looks at both a.obj and b.obj, it sees two declarations of MyWindowHandle. The linker then gives the error that you have multiple definitions of MyWindowHandle.

    One solution is to use the extern keyword for the globals in one module, and not use extern in the other module -- this has been discussed here many times (so a search will bring up those threads). Also any good C++ book explains the usage of extern for global variables.

    But that is an inferior solution -- the real "solution" is to not use global variables and design your code differently so that there is no need for globals.

    Regards,

    Paul McKenzie

  3. #3
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,244

    Re: Make HWND global LNK2005

    To complete a little what Paul already stated:

    Generally, in a Win32 application it's not necessary to store window handles.
    That's because the window procedures get the window handle as parameter, then you can further pass it to handler functions.
    Also, the notification messages come with the child window handles.
    Also, there are WinAPI functions which can easily get a window handle (e.g. GetDlgItem).
    And so on...

    [ Moved thread ]
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: https://codexpertro.wordpress.com/

  4. #4
    Join Date
    Feb 2012
    Posts
    19

    Re: Make HWND global LNK2005

    Okay, but in fact I cant see *where* i declared MyWindowhandle two times, thats what surprised me. Do you see it? I just declared it in the GUI.h Nowhere else. I think my linker is kidding me

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Make HWND global LNK2005

    Quote Originally Posted by ImNotaBot View Post
    Okay, but in fact I cant see *where* i declared MyWindowhandle two times, thats what surprised me. Do you see it?
    I see it clearly.
    I just declared it in the GUI.h Nowhere else. I think my linker is kidding me
    Did you read my explanation? I'll quote again:
    When you use an include file, all you're doing is taking the text from the include file and placing it into your source file.
    You did this:
    Code:
    #include "GUI.h"
    In both your source files. So what does GUI.h contain?

    Regards,

    Paul McKenzie

  6. #6
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,633

    Re: Make HWND global LNK2005

    I just declared it in the GUI.h Nowhere else.
    You have to learn what #include actually does.
    Best regards,
    Igor

  7. #7
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,244

    Re: Make HWND global LNK2005

    Quote Originally Posted by ImNotaBot View Post
    I think my linker is kidding me
    A linker is never kidding. It just reports the mistakes you made.
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: https://codexpertro.wordpress.com/

  8. #8
    Join Date
    Feb 2012
    Posts
    19

    Re: Make HWND global LNK2005

    Okay now i understood what u want to tell me. But is this

    Code:
    #ifndef somethingThatShouldNotBeDuplicated
    #define somethingThatShouldNotBeDuplicated
    #endif
    not exactly to avoid the duplictated inclusion?

    greets and thanks for help.

  9. #9
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,430

    Re: Make HWND global LNK2005

    Quote Originally Posted by ImNotaBot View Post
    Okay now i understood what u want to tell me. But is this

    Code:
    #ifndef somethingThatShouldNotBeDuplicated
    #define somethingThatShouldNotBeDuplicated
    #endif
    not exactly to avoid the duplictated inclusion?
    Indeed it is "to avoid the duplictated inclusion" in the SAME module. But it cannot avoid the inclusion in another module!
    Victor Nijegorodov

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Make HWND global LNK2005

    Quote Originally Posted by ImNotaBot View Post
    Okay now i understood what u want to tell me. But is this

    Code:
    #ifndef somethingThatShouldNotBeDuplicated
    #define somethingThatShouldNotBeDuplicated
    #endif
    not exactly to avoid the duplictated inclusion?
    I'll quote once again:
    When you use an include file, all you're doing is taking the text from the include file and placing it into your source file.
    You're still not taking that quote and understanding it clearly.

    You have two different modules, A.CPP and B.CPP. Each one of those files has #included that GUI.H header. So again, take the text in that header and copy/paste it in each one of those modules. That is what you end up with, and that is what the compiler is compiling.

    Now ask yourself, how is A.CPP and B.CPP supposed to know that each other has seen your definition? What is this magic communication that each has? There isn't any. All the compiler sees is what it sees.

    Now you have two object files created from compiling, A.OBJ and B.OBJ, so they still have that declaration in each one, and the linker sees both definitions.

    Regards,

    Paul McKenzie

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured