现在的位置: 首页 > 综合 > 正文

一步步用SDK构建记事本程序(二)

2018年05月14日 ⁄ 综合 ⁄ 共 3131字 ⁄ 字号 评论关闭

 上一篇文章仅仅写了个框架未实现什么功能。

下面来添加功能。

 

对了,这里不要疏忽一个问题。不要急于编码,呵呵,我刚才有点急于编码了:)

编码之前要保持设计清晰,否则可能到开发后期,功能逻辑复杂是的我们迷惑于其中了。

 

整理一个记事本大体结构:

 

接下来,考虑下界面是什么样子:

例如Windows的记事本程序:

这里不需要MDI(多文档视图),为了偷懒好听点说是简单起见 我将Edit子视图(其实在这里就是个子窗口)

直接在第一篇写的框架所生成的主窗口MainWindow里创建。

 

这里需要在主窗口创建的东西有:菜单栏,如果需要还可以加如工具栏;Edit窗口;状态栏。

创建这些控件(Static,Edit,RichEdit,Button...)都使用CreateWindow加具体控件类名来生成的,只要记住控件也是窗口就好了,拿Edit控件来说,在MFC里面表现为

class CEdit : public CWnd
 
下面创建Edit窗口,我这里用的是RichEdit.
关键代码
hwndRichEdit = CreateWindow(TEXT("RichEdit"),TEXT(""),WS_CHILD | WS_VISIBLE,
   0,0,800,600,
   hWnd,NULL,GetModuleHandle(NULL),NULL);
在这里顺便把主菜单也实现了
操作如下:
1.VS2008主菜单“项目”->添加新项
 
添加一个资源文件resource.rc(文件名自定)
 
右键菜单点击“添加资源”
 
新建一个Menu
 
将菜单ID命名为IDR_MENU_MAIN
修改程序,我之前在程序框架里有关主菜单引用的地方都被赋值为NULL了:)
在窗口类注册的地方和创建主窗口的地方均有对菜单ID的引用
我们来改
在注册窗口类前
wcex.lpszMenuName = NULL; -> wcex.lpszMenuName = IDR_MENU_MAIN;
别忘了在程序代码开始的地方添加对资源引用的头文件resource.h
编译一下吧:)
这里还要说的一点 对于RichEdit控件创建后无法直接显示 必须调用InitCommonCtrls()这个函数和装载对应的控件库(.dll)
【以上文章和以下代码如果那里不妥,或有好的建议请留言指出,谢谢。正好学习交流下:)】
完善后的代码:
  1. #include <windows.h>
  2. #include <commctrl.h>
  3. #include "resource.h"
  4. #pragma comment(lib,"comctl32")
  5. LRESULT CALLBACK WndProc(HWND hWnd,UINT uMessage,WPARAM wParam,LPARAM lParam);
  6. int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
  7. {   
  8.     WNDCLASSEX  wcex = {0};
  9.     TCHAR       szAppName[] = TEXT("SigmaTera Notepad");
  10.     MSG         msg = {0};
  11.     HWND        hWnd = NULL;
  12.     //填充窗口类结构
  13.     wcex.cbClsExtra = 0;
  14.     wcex.cbSize = sizeof (WNDCLASSEX);
  15.     wcex.cbWndExtra = 0;
  16.     wcex.hbrBackground = (HBRUSH)COLOR_WINDOW;
  17.     wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
  18.     wcex.hIcon = LoadIcon(hInstance,IDI_APPLICATION);
  19.     wcex.hIconSm = wcex.hIcon;
  20.     wcex.hInstance = hInstance;
  21.     wcex.lpfnWndProc = WndProc;
  22.     wcex.lpszClassName = szAppName;
  23.     wcex.lpszMenuName = (LPCTSTR)IDR_MENU_MAIN;
  24.     wcex.style = CS_HREDRAW | CS_VREDRAW;
  25.     InitCommonControls();
  26.     HMODULE hRichEditLib = LoadLibrary(TEXT("RICHED32.DLL"));
  27.     //注册窗口类
  28.     if (RegisterClassEx(&wcex) == NULL)
  29.     {
  30.         return -1;
  31.     }
  32.     //创建窗口
  33.     hWnd = CreateWindow(szAppName,TEXT("Notepad"),WS_OVERLAPPEDWINDOW,
  34.                         CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
  35.                         NULL,NULL,hInstance,NULL);
  36.     
  37.     if (NULL == hWnd)
  38.     {
  39.         return -1;
  40.     }
  41.     //显示并更新窗口
  42.     ShowWindow(hWnd,SW_SHOW);
  43.     UpdateWindow(hWnd);
  44.     //消息循环
  45.     while (GetMessage(&msg,NULL,0,0))
  46.     {
  47.         TranslateMessage(&msg);
  48.         DispatchMessage(&msg);
  49.     }
  50.     FreeLibrary(hRichEditLib);
  51.     return 0;
  52. }
  53. LRESULT CALLBACK WndProc(HWND hWnd,UINT uMessage,WPARAM wParam,LPARAM lParam)
  54. {
  55.     static HWND hwndRichEdit = NULL;
  56.     
  57.     switch (uMessage)
  58.     {
  59.     case WM_CREATE:
  60.         hwndRichEdit = CreateWindow(TEXT("RichEdit"),TEXT(""),WS_CHILD | WS_VISIBLE,
  61.             0,0,800,600,
  62.             hWnd,NULL,GetModuleHandle(NULL),NULL);
  63.         break;
  64.     case WM_CLOSE:
  65.         DestroyWindow(hWnd);
  66.         break;
  67.     case WM_DESTROY:
  68.         PostQuitMessage(0);
  69.         break;
  70.     }
  71.     /*else if (uMessage == WM_CLOSE)
  72.     {
  73.         
  74.     }
  75.     else if (uMessage == WM_DESTROY)
  76.     {
  77.         
  78.     }*/
  79.     return DefWindowProc(hWnd,uMessage,wParam,lParam);
  80. }

抱歉!评论已关闭.