永发信息网

c++ 里有几种可以创建windows 窗口的方法

答案:2  悬赏:60  手机版
解决时间 2021-05-17 07:03


#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HelloWin") ;
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 (WHITE_BRUSH) ;//获取一个图形对象,在这个例子中,是获取绘制窗口背景的刷子
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;

if (!RegisterClass (&wndclass))//为程序窗口注册窗口类
{
return 0 ;
}
//根据窗口类创建一个窗口
hwnd = CreateWindow (szAppName,
TEXT ("一个简单的Win32程序"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL) ;

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)
{
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;

switch (message)
{


case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ; //开始窗口绘制

GetClientRect (hwnd, &rect) ; //获取窗口客户区的尺寸

DrawText (hdc, TEXT ("Hello, 欢迎使用Turbo C for Windows 集成实验与学习环境!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; //显示文本串

EndPaint (hwnd, &ps) ; //结束窗口绘制
return 0 ;

case WM_DESTROY:
PostQuitMessage (0) ; //在消息队列中插入一条“退出”消息
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam);//执行默认的消息处理
}
这个属于哪一种方式创建窗口的!

还有就是我发现有一种没有带int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)

这个头文件的!

直接使用继承基类的方法创建窗口的!

那他们这两种创建方式分别叫什么创建方法的啊!
哪一种更适合初学vc++的去学呢

谢谢,知道的朋友麻烦说一下下@

最佳答案
推荐一本好书《Windows程序设计(第五版)》。经典的。
全部回答
//创建对话框 BOOL CMainDlg::CreateMainDlg() { m_hDlg = CreateDialog(m_hInst,MAKEINTRESOURCE(IDD_MAIN_DLG),NULL,MainDlgProc); if(m_hDlg == NULL) { return FALSE; } ShowWindow(m_hDlg,TRUE);//显示窗口 return TRUE; } //真正的消息处理函数,在这里可以任意调用对象的成员函数 BOOL CMainDlg::CallDlgProc(HWND hWnd,UINT wMsg,WPARAM wParam,LPARAM lParam) { switch(wMsg) { case WM_INITDIALOG: TempTestFuncion(); //norains:测试的私有函数 break; } return FALSE; } 这是在主程序中对类的的调用: ////////////////// //MainApp.cpp ////////////////// #include "stdafx.h" #include "MainDlg.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { //声明一个对象 CMainDlg mainDlg(hInstance); //创建并显示窗口 if(mainDlg.CreateMainDlg() == FALSE) { return 0x05; } //消息循环 MSG msg; while(GetMessage(&msg,NULL,0,0)) return 0; } 这段代码的关键点在于MainDlgProc声明为类的static函数,以及使用g_pDlg来存储this对象指针,并在MainDlgProc中调用。只要注意到这两点,在类中创建一个窗口就不是一件非常困难的事情。 对于CallDlgProc()函数,可能有不少人觉得是鸡肋,因为相同的功能完全可以在MainDlgProc()中实现,比如这程序的代码完全可以撇开CallDlgProc()写成这样: BOOL CALLBACK CMainDlg::MainDlgProc(HWND hWnd,UINT wMsg,WPARAM wParam,LPARAM lParam) { if(g_pDlg != NULL) { switch(wMsg) { case WM_INITDIALOG: g_pDlg->TempTestFuncion(); break; } } return FALSE; } 所完成的功能和之前的代码相同。不过如果要更改之后的代码正常工作的话,还需要把TempTestFuncion()函数声明为public。也许有的读者已经发现问题之所在:如果对消息相应的处理函数不多,这样倒是可以;但如果很多的话,那么那些消息相应函数都需要声明为public,并且这些消息响应函数都是用户不可能用到的!用户看到如此之多用不到的public函数,即使没头晕,也需要好一阵子才能回神过来。 所以呢,CallDlgProc()函数只是起到一个缓冲作用,不必要把所有的消息相应函数都暴露给用户。虽然这样做也暴露了CallDlgProc()函数,但毕竟相对于上十个甚至上百个消息响应函数而言,仅仅只是暴露一个没什么作用的CallDlgProc()函数函数,应该能让用户减轻不少负担才是。 在网上看到有一个方法不是采用全局变量,而是直接设置窗口数据,然后再获取。这方法比较有意思,在此将更改的代码贴出: BOOL CMainDlg::CreateMainDlg() { m_hDlg = CreateDialog(m_hInst,MAKEINTRESOURCE(IDD_MAIN_DLG),NULL,MainDlgProc); if(m_hDlg == NULL) { return FALSE; } ShowWindow(m_hDlg,TRUE);//显示窗口 SetWindowLong(m_hDlg,GWL_USERDATA,(LONG)this); //将this指针传递给窗口 return TRUE; } BOOL CALLBACK CMainDlg::MainDlgProc(HWND hWnd,UINT wMsg,WPARAM wParam,LPARAM lParam) { static CMainDlg * pDlg = NULL; if(pDlg == NULL) { pDlg = (CMainDlg *)GetWindowLong(hWnd,GWL_USERDATA); }  if(pDlg != NULL) { switch(wMsg) { case WM_INITDIALOG: pDlg->TempTestFuncion(); break; } } return FALSE; } 这段代码关键就只在于两个函数:SetWindowLong()和GetWindowLong().很巧妙地让窗口通过这两个函数来传输this对象,的确是一个很好的方法.
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
铁道车辆、电力机车、内燃机车、动车组哪个的
龙之谷战士有横斩这个技能吗?
铁锋区齐齐哈尔诗黛尔专卖地址在什么地方,想
英语一至六年级见面英语句子
前几天晚上哭过后眼睛肿到现在怎么办啊?
求贺军翔的电视剧、电影....所有........
鹤城区锦溪小学-怀化市财校地址在哪里啊
身份证加急办理到底需要多久
北京现代车型最便宜的要多少钱
2009中韩歌会的所有曲目
渭南到郑州的列车车次
最贵的冰果多钱一根
龙亭区开封仁和旅社我想知道这个在什么地方
全家旅游回来祝福语,全家福的祝福语
声卡设备卸载后无法恢复
推荐资讯
谁能给我一个魔域BOSS版激活码啊?
任洪恩演唱的豫剧《我爱我爹》MP3下载地址
冰心说过的一句名言:爱于什么,更不在于什么,
中医的发展方向
老河口市襄樊现代厨卫在什么地方啊,我要过去
为什么“生于忧患,死于安乐”文中说舜用“发
头发拉直和洗直有什么不一样呢 哪种好点呢
该怎么办?继续?还是分开?
804是到厦门火车站的吗
CS online和CF哪个更好玩???
小肠间质瘤痊愈
天津中德南院的环境好不好?
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?