2011-09-02 142 views
0

我正在製作一個簡單的GUI庫,並且已經進行了第一次測試。奇怪的是,沒有一個窗口宏似乎被定義。我收到錯誤,如「'NULL'未在範圍內聲明」和「'HANDLE'未在範圍內聲明。」我認爲這可能是我組織代碼的方式,因爲入口文件easywin.hpp中的東西也沒有定義,但它像它應該工作的SEEMS。 easywin.hpp(大多數):Windows.h宏未定義

#ifndef EASYWIN_BASE_HPP 
#define EASYWIN_BASE_HPP 

#include <string> 
#include <map> 

//Strings are used everywhere, so might as well use them globally 
using std::string; 

/** 
* A namespace to encapsulate WinAPI and prevent name clashing. 
**/ 

namespace WinAPI{ 
    #include <windows.h> 
    #include <commctrl.h> 
} 

//header includes (ordered according to inheritance) 
#include "Application.hpp" 
#include "Object.hpp" 
    #include "Widget.hpp" 
     #include "Container.hpp" 
      #include "Window.hpp" 
       #include "Dialog.hpp" 
        //not implemented yet, so don't include 
        //#include "Light.hpp" 
        #include "Heavy.hpp" 
      // there are more container types 
     #include "Control.hpp" 
      #include "Textbox.hpp" 
     #include "Tooltip.hpp" 

//source includes 
//needed to simplify class dependencies 
#include "Application.cpp" 
#include "Object.cpp" 
    #include "Widget.cpp" 
     #include "Container.cpp" 
      #include "Window.cpp" 
       #include "Dialog.cpp" 
        //not implemented yet, so don't include 
        //#include "Light.cpp" 
        #include "Heavy.cpp" 
      // there are more container types 
     #include "Control.cpp" 
      #include "Textbox.cpp" 
     #include "Tooltip.cpp" 

#endif 

我只是不明白。如果我在這個文件中包含所有內容,那麼這些文件應該得到這個文件中定義的內容。我做錯了什麼?

編輯:爲了鼓勵更好的答案,我會後git倉庫:

https://github.com/PiMaster/Easywin

+0

下面兩個答案都沒有回答我的問題。我看不出任何會導致這種情況的原因。所有文件都包含在文件中,該文件包含/定義了包含/定義之後從未包含/定義的內容。有人知道爲什麼這不起作用!? – ConsciousCode

回答

0

這應該是IronMensan的答案評論,因爲這是完全正確的,但我不適合在那裏......

窗戶的API有取型「處理」的參數,在全局命名空間功能,換言之「:: HANDLE」。 Windows庫已編譯爲,編譯代碼存在於user32.lib/dll等庫中。

windows.h的目的是定義庫中存在的已有的類型和函數,以便您可以調用它們。你所做的是定義一些不相關的類型,例如WinAPI :: HANDLE,這很好,但決不會改變庫包含需要:: HANDLE作爲參數的函數的事實。

我明白你想要做什麼,這是一個很好的目標。然而,它不可能有效。

+0

雖然這可能會有所幫助,但它仍然不能解決我眼前的問題。由於某些原因,包含文件中的任何內容都沒有被註冊爲在其他任何文件中定義的內容,即使它們在包含這些文件之前已被定義/包含。 – ConsciousCode

+0

你認爲你在哪裏定義了「HANDLE」? – jcoder

+0

HANDLE應該在windows.h中定義。我的編譯器說,它沒有被定義,即使我將WinHe中的windows.h取出。不過,我想我有一個想法。編譯器似乎在編譯我的.cpp文件之前的任何其他文件 - 我應該把我的函數定義在其他.hpp文件? – ConsciousCode

0

大多數的時候,這樣的事情發生在我身上,這是因爲保護宏的雙重定義。這通常發生在您複製並粘貼頭文件並忘記更改保護宏時。嘗試在其他文件中搜索EASYWIN_BASE_HPP。在較新的編譯器上,您還可以使用#pragma once使其更簡單。

此外,在頭文件中使用using通常不是一個好主意。頭文件的用戶可能會使用來自不同庫的多個頭文件。其中之一可能與string標識符有衝突。

+0

搜索顯示easywin.hpp是包含EASYWIN_BASE_HPP定義的唯一文件。我已經將使用std :: string移至easywin。任何其他想法? – ConsciousCode

3

您需要擺脫WinAPI命名空間。即使您設法通過使用WinAPI ::作用域來編譯所需的東西,鏈接器也將無法找到任何東西,但仍然無法構建。

爲避免名稱衝突,應將所有代碼放在單獨的名稱空間中,並使Windows.h保持獨立。

+0

我喜歡將WinAPI保存在名稱空間中的想法 - 這就像將它放在一個盒子中一樣。另外,我可能想擴展我的庫以包含套接字編程,並且窗口決定使用我想在winsock.h文件中使用的名稱。我沒有理由認爲鏈接程序不能找到任何東西,因爲我已經在一個更簡單的項目中測試了在命名空間中封裝windows.h,並且它工作正常。 所以,這個答案對我來說完全沒用**,因爲你沒有回答我的問題,甚至沒有說出與這個話題相關的任何東西。 – ConsciousCode

+0

@PiMaster'typedef void * HANDLE'是windows.h的一部分;它不是預處理符號。所以,如果你把windows.h放在'namespace WinAPI'中,它將變成'WinAPI :: HANDLE'。因此,我對「用WinAPI ::需要它的範圍」做出的評論回答了你的問題。 – IronMensan

+0

@PiMaster - 您可能喜歡將windows.h保存在一個盒子中的想法,但您似乎錯誤地認爲它是在過去的10年中構建的頭文件,旨在容納C++。你不能再犯這個錯誤了。 –