posts - 4,  comments - 0,  trackbacks - 0

   引擎从何处开始,到何处结束。引擎当然从入口点开始,对c/c++程序员而言,控制台程序始于main(),win32程序始于WinMain()。一个显而易见的事实,它从朴素的程序框架开始,而不是各种夺目的功能和特效。
   假如我们同时需要控制台和win32窗口呢?需要它的可能理由:
   ①一个方便调试的控制台,在发布时,随时可以把它屏蔽。
   ②从命令行执行不同的模式
   ③尽可能简单的程序入口点

   一种解决办法比较笨拙,使用预定义,如OGRE:
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif

   另一种解决办法是在main()和WinMain()中调用同一个函数run(),且通过GetModuleHandle(NULL)获取CreateWindowEx前registerWindowClass需要的HInstance。
   windowClass.hInstance   = winState.appInstance;
   用全局的winState.appWindow保存创建的窗口句柄。大致代码如下(来源于Torque引擎),不再赘述。

struct Win32PlatState
{
     HINSTANCE hinstOpenGL;
     HINSTANCE hinstGLU;
     HWND appWindow;
     HDC appDC;
     HINSTANCE appInstance;
     HGLRC hGLRC;
}; 

Win32PlatState winState;

//--------------------------------------
static int run(int argc, const char **argv)
{
      // 伪码
     int ret = mst->main(argc, argv);
     Platform::createWindow();
     Platform::process();

     return ret;
}

//--------------------------------------
int main(int argc, const char **argv)
{
     winState.appInstance = GetModuleHandle(NULL);
     return run(argc, argv);
}

//--------------------------------------
int PASCAL WinMain(HINSTANCE hInstance,
                      HINSTANCE hPrevInstance,
                      LPSTR    lpCmdLine,
                      int       nCmdShow)
{
     std::vector<char *> argv;
     char moduleName[256];
     GetModuleFileNameA(NULL, moduleName, sizeof(moduleName));
     argv.push_back(moduleName);

     for (const char* word,*ptr = lpCmdLine; *ptr; )
     {
         // Eat white space
         for (; isspace(*ptr) && *ptr; ptr++)
              ;

         // Pick out the next word
         for (word = ptr; !isspace(*ptr) && *ptr; ptr++)
              ;

         // Add the word to the argument list.
         if (*word)
         {
              int len = ptr - word;
              char *arg = (char *) malloc(len + 1);
              strncpy(arg, word, len);
              arg[len] = 0;
              argv.push_back(arg);
         }
     }

     winState.appInstance = hInstance;
     int retVal = run(argv.size(), (const char **) argv.front());
     for(unsigned int j = 1; j < argv.size(); j++)
         free(argv[j]);

     return retVal;
}

参考链接:
   Getting the HWND and HINSTANCE of the Console Window
   http://bobobobo.wordpress.com/2008/02/03/getting-the-hwnd-and-hinstance-of-the-console-window

posted on 2010-09-30 14:23 龙湖 阅读(336) 评论(0)  编辑 收藏 引用 所属分类: 引擎实战
只有注册用户登录后才能发表评论。