windows开发记事本程序纪实(二)逻辑篇1_其它综合

1. 主要内容

从本节开始介绍windows开发实现记事本程序的逻辑实现部分。本节的主要内容有以下3点:

1. 主窗口定义 —— 主要介绍记事本主界面窗口对应的窗口类及实现方案

2. RichEdit控件的选用及初始化 —— 记事本程序中编辑控件的选择及使用

3. 整个程序ICON的选择。—— 程序ICON设置

2. 实际开发

2.1 主窗口实现

在上一篇介绍界面的实现中只是给出了运行界面的效果,但是当时那个界面程序不能响应任何的windows消息,因为当时的窗口在创建时将窗口对应的过程处理函数设置为NULL。现在,我们需要将相应的过程处理函数添加上使得这个记事本应用程序可以响应我们发出的一系类操作指令。为此,本文在开发时,单独设计了一个用于保存主界面窗口的类CMainWnd。这个类定义了整个窗口的过程处理函数Main_Porc。在Main_Proc中可以对传入的任何消息进行处理(包括初始化窗口消息,窗口中其他控件的消息,关闭窗口消息等等)。以windows 自带记事本为例,如图1所示

图1 windows主窗口消息效应区域

如上图所示,在windows记事本主界面中,需要响应红色矩形区域内的菜单控件的各类消息、响应黄色矩形区域内系统按钮的相关消息,以及相应编辑控件Edit中的消息。对于主窗口中的各类控件的消息,windows会以WM_COMMAND消息进行传输,这也是整个程序的核心处理区域。系统按钮关闭的消息则是WM_CLOSE。窗口初始化消息WM_INITDIALOG则是构建对话框窗口前发出的初始化消息。为了能够响应上述各类消息,需要在CMainWnd中添加对于这几类消息的响应函数,因此整个CMainWnd的基本实现形式如下:

头文件声明:

/************************************************************************/
/* file  : CMainWnd.h
 * author : Huagang Li
 * date  : 2014-8-30 15:29:42
 * blogs : http://www.cnblogs.com/lhglihuagang/
 * tips  : 主窗口实现类, 实现窗口的过程函数,消息响应函数等
 */
/************************************************************************/
#ifndef _MAIN_WND_H
#define _MAIN_WND_H

#include <Windows.h>
//////////////////////////////////////////////////////////////////////////
// CMainWnd 主窗口类,提供

class CMainWnd
{
public:
  static BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  static BOOL Main_OnInitDialog(HWND hWnd, HWND hWndFocus, LPARAM lParam);
  static void Main_OnCommand(HWND hWnd, int id, HWND hWndCtl, LPARAM lParam);
  static void Main_OnClose(HWND hWnd);

private:
  static HWND hMainWnd;  // 主窗口句柄
};

#endif

CMainWnd具体定义:

#include "MainWnd.h"
include <WindowsX.h>
//////////////////////////////////////////////////////////////////////////
// static data members
HWND CMainWnd::hMainWnd = NULL;
//////////////////////////////////////////////////////////////////////////
// static function members
// 主窗口的过程函数,根据消息类型处理各类消息
BOOL WINAPI CMainWnd::Main_Proc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
 switch (uMsg)
 {
 HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog);
 HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand);
 HANDLE_MSG(hWnd, WM_CLOSE, Main_OnClose);
 }
</span><span style="color: #0000ff">return</span><span style="color: #000000"> FALSE;
}
BOOL CMainWnd::Main_OnInitDialog( HWND hWnd, HWND hWndFocus, LPARAM lParam )
{
 return TRUE;
}
// id为具体空间的ID号,可以在resource中定义有意义的控件ID,如“打开文件”可以设置
// 为ID_FILE_OPEN
void CMainWnd::Main_OnCommand( HWND hWnd, int id, HWND hWndCtl, LPARAM lParam )
{
 switch (id)
 {
 //
 }
}
void CMainWnd::Main_OnClose( HWND hWnd )
{
 ::EndDialog(hWnd, NULL);
}

在定义了CMainWnd后,在main函数处的DialogBox处添加主窗口的过程处理函数

::DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, CMainWnd::Main_Proc);

完成上述步骤运行后,就可以看到启动后的主界面可以响应窗口上系统按钮“关闭”,但是对于菜单控件的消息,因为消息响应此还是函数中数什么都没有做,因此还是不会进行任何处理。

2.2 RichEdit控件的选用

      对于一个记事本程序来说,主界面上核心区域还是编辑区域。但是当前记事本程序中还没有选择任何编辑控件。通过观察现有windows控件列表可以看出,适合编辑控件的有Edit Control以及Rich Edit2.0 Control。对于这两种编辑控件,Edit Control较为简单,但是响应的功能也较少。Rich Edit2.0 Control实现起来较为复杂,但是对应的功能也多了不少(例如可以改变字体颜色,字号等等)。本文希望能够实现一个功能较强的记事本,因此选择了Rich Edit2.0 Control进行后续开发。插入了Rich Edit2.0 Control后,主界面窗口对应的资源视图如图2所示:

图2 IDD_MAIN中插入Rich Edit2.0 Control

      上述步骤运行后,本以为可以看到带有编辑界面的记事本程序,可是实际上程序运行后没有任何效果,甚至主界面都不能正常启动了。百度后发现,对于richedit启动失败的方法都是针对MFC程序来说的,需要添加初始化函数AfxInitRichEdit2。但是现在使用windows API 开发,并没有AfxInitRichEdit2这个函数,只能另寻他路了。终于在一篇博文中http://blog.csdn.net/dijkstar/article/details/7953816提到,原来上面那个初始化函数中主要是加载RichEdit依赖的dll,那么整个问题就豁然开朗了,我们只需要在主窗口启动前手动的载入这个dll就可以了。因此在主函数的DialogBox前添加了依据载入dll的操作如下:

::LoadLibrary(T("riched20.dll"));

MAIN的properties中:

此时再运行程序时,可以正常启动记事本了,且能够在richedit中进行编辑,效果如图3所示:

图3 手动加载Riched20.dll后出现主界面窗口

      在启动主界面后,可以正常进行编辑。貌似这个控件可以正常工作了。但在实际测试时,发现了以下几个问题:

1. 界面运行后RichEdit边框棱角过于分明

    处理方法: Richedit控件的properties  -> Boarder –> Flase

2.输入Enter 不能换行(手动输入时一直在同一行编辑)

   处理方法: Richedit控件的properties  -> Multiline–> True

                      Richedit控件的properties  -> Want Return–> True

3. 没有滚动条(横向以及纵向的)

    这个在主界面属性上,IDD

   处理方法: IDD_MAIN-> properties  -> Horizontal Scrollbar–> True

                      IDD_MAIN –> properties  -> Vertical Scrollbar–> True

4. 不能随窗口大小伸缩

    在对窗口进行伸缩时,RichEdit控件的大小还是保持原来的大小,如图4所示:

图4 主界面大小变化时RichEdit控件大小不变

    这个问题其实很好理解,因为伸缩主界面窗口时,windows将发送WM_SIZE消息通知窗口。这个过程类似于windows对主界面窗口说“hi, 你的大小已经变了,你根据改变后的大小变一下”。现在我们的主窗口过程处理函数中并没有针对WM_SIZE消息对RichEdit进行特殊处理,因此主界面下面的RichEdit一直保持自己原来的大小,才会出现上面的情况。那么具体的解决方案为:在InitDialog中添加RichEdit大小自适应功能,同时针对WM_SIZE消息,添加Main_OnSize函数来处理这种独立的控件。具体的代码实现如下:

void CMainWnd::Main_OnSize( HWND hWnd, UINT state, int cx, int cy )
{
 RECT stRect;
 ::GetClientRect(hWnd, &stRect); // 获取窗口客户区大小
</span><span style="color: #008000">//</span><span style="color: #008000"> 将RichEdit大小调整为客户区大小</span>
 ::MoveWindow(::GetDlgItem(hWnd, IDC_RICHEDIT), stRect.left, stRect.top,
 stRect.right-stRect.left, stRect.bottom-stRect.top, TRUE);
}

这里只是在CMainWnd中添加了对于WM_SIZE的消息响应函数,要让RichEdit响应这个消息,还需要在Main_Proc中添加相应过程

HANDLE_MSG(hWnd, WM_SIZE, Main_OnSize);

这样,RichEdit也就可以跟着主窗口大小自由伸缩了。上述过程处理函数中,主要调用了三个基本的API接口。

1. GetClientRect,这个API用于获取客户区大小,RichEdit伸缩的大小就是这个大小值

2. GetDlgItem 获取窗口下某一个控件的句柄,例如GetDlgItem(hWnd, IDC_RICHEDIT),就可以获得主窗口下RichEdit控件对应的句柄。

3. MoveWindow。它的第一个参数就是需要进行位置大小变化的窗口句柄。我们这里将2中的RichEdit句柄传入,后面的参数分别是矩形区域的left点,top点,width值以及height值。最后一个参数用来表示大小改变后要不要重绘窗口。注意,这里选择了TRUE。如果选择FALSE,会出现以下这种情况:当将窗口变小后,在进行变大操作,RichEdit并没有立即适应变大后的区域,还是保留在原来变小的区域。效果如图5所示:

图5 MoveWindows中参数repaint设置为FALSE后潜在问题

基于此,我们在用MoveWindow改变窗口大小时,最好使得repaint为TRUE,保证实时改变。

2.3 主程序ICON设计

      在上述截图中可以看出,主界面的左上角ICON一直是windows自带的ICON。为了与windows自带记事本做到类似,直接到网上找了一个类似的JPG图标转为ICO,然后设置了程序的ICON。具体的图标设置方法请参考http://www.cnblogs.com/lhglihuagang/p/3927283.html

      在图标设置后,可以运行程序查看下最新的效果,如图6所示

图6 设置程序图标后的结果

      最后,对话框窗口的标题Dialog实在显得有些另类,这里根据windows自带记事本的标题“无标题 - 记事本”,将这个值进行了相应的修改,具体为IDD_MAIN-> properties  -> Caption –> 无标题 - 记事本最后,对话框.

3. 运行结果

在添加了CMainWnd以及RichEdit后,整个程序的运行后效果如下图7所示:

图7 本节程序改动后的效果

4. 结论

    1. 使用RichEdit控件时,需要手动加载riched20.dll,否则程序运行后没有任何界面效果

      2. RichEdit换行、滚动条、边框都可以通过properties中相应字段进行设置

      3. 需要在CMainWnd中添加WM_SIZE消息响应函数,保证RichEdit自由伸缩。

5. 参考链接

      [1] http://blog.csdn.net/dijkstar/article/details/7953816

    [2] http://www.cnblogs.com/lhglihuagang/p/3927283.html

    [3] http://msdn.microsoft.com/en-us/library/ms633534(VS.85).aspx

6. 说明

     这将是一个系列博文,后面会继续补充逻辑功能的开发的步骤。希望能与更多博友交流。 如果你觉得这篇文章还可以,请点赞,哈哈~~
      声明:未作说明,则本文为年糕原创。      注意:转载须保留全文,如需修改请 联系作者。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索windows
, 开发
记事本程序
windows记事本、windows记事本在哪里、windows记事本下载、windows7记事本在哪、windows10记事本,以便于您获取更多的相关知识。

时间: 2024-07-30 17:35:59

windows开发记事本程序纪实(二)逻辑篇1_其它综合的相关文章

windows开发记事本程序纪实(一)界面篇_相关技巧

前言 从毕业开始学习windows UI编程,工作中总是和一些API打交道,但是从没有做过一个完整的界面程序.因此打算自己利用空余时间做一个小的项目来总结自己所学的东西.在网上看到许多人建议自己动手写完整的项目才能快速提高,因此打算从仿照windows的记事本开始,真正实现一个基本的windows界面程序.考虑到编写一个完整的windows 记事本程序需要大量的工作,因此打算将每一个阶段的成果记录下来,一方面能够帮助自己进行总结,回顾已学的知识,另一方面也能够与其他网友一起讨论,从而可以在讨论中

C++ Builder 6中开发Office程序心得(二)

(四) 单元格的操作 单元格的操作实际上就是对范围(Range)的操作.一般的代码段如下: RangePtr r; r=EWS4->get_Range(V("a1"), V("a1")); r->set_Value(V("Species No")); 所以,对单元格内容的操作实际就是先获得一个要操作的范围(Range),然后再set_Value的过程. 和数据库连接并不很困难.将数据库中的数据写到Excel Worksheet中也不是

Python面向对象编程 - 一个记事本程序范例(二)

给程序加上控制台菜单 menu.py import sys from notebook import Notebook, Note class Menu: '''Display a menu and respond to choices when run.''' def __init__(self): self.notebook = Notebook() self.choices = { "1": self.show_all_notes, "2": self.sea

Windows Azure入门教学系列 (二):部署第一个Web Role程序

本文是Windows Azure入门教学的第二篇文章. 在第一篇教学中,我们已经创建了第一个Web Role程序.在这篇教学中,我们将学习如何把该Web Role程序部署到云端. 注意:您需要购买Windows Azure Platform 服务才能继续本教学.您可以通过点击https://mocp.microsoftonline.com/Site/Support.aspx页面上的   联系我们的支持团队来获得购买服务的具体步骤或询问其他有关购买,收费的问题. 在开始本教学之前,请确保你从Win

Windows 8开发入门(十二) windows 8的文件管理 1

File创建和String Stream Buffer方式读写 在本文中我们将学习Windows 8中的文件创建和多种读写方式以及设置文档库访问权限和文件类型的访问. 当然我们需要做以下准备工作: 首先:设置程序允许访问的文件位置为:"库\文档",设置方法:点击"Package.appxmanifest ",然后选择"功能"选项卡,在功能列表中勾选"文档库访问".如下图: 开发入门(十二) windows 8的文件管理 1-w

如何更换Windows XP下的默认记事本程序

XP下的记事本使用的频率还是比较高的,但是它却缺少行数显示,而且编写脚本什么的没有高亮显示,以至于有时候英文拼写错了都不知道(尤其是像我这种英文差的人).Vista下的记事本就好用很多了,不过Vista要求太高了,所以今天就是要用一款功能更强的Notepad2来替换XP下的记事本. 废话不说了,首先下载Notepad2汉化版保存在D盘,解压出notepad2.exe到D盘,改名为notepad.exe 然后分别拷贝到"c:\windows\system32\dllcache\".&qu

《C语言开发从入门到精通》一2.2 在Windows环境下开发C程序

2.2 在Windows环境下开发C程序 知识点讲解:光盘:视频\PPT讲解(知识点)\第2章\在Windows环境下开发C程序.mp4 DOS环境对广大读者来说十分陌生,并且在DOS下进行开发也十分麻烦.为此,专门推出了Windows环境下的开发工具.Win-TC其实就是一种Windows环境下的开发工具,但是其功能和Turbo C基本类似,只是在编译和运行上更加方便而已.随着计算机技术的发展,编程工具也随之更新换代.目前最受程序员喜爱的开发工具,当属微软的Visual Studio. 2.2

在 Visual Studio 2010 中开发和部署 Windows Azure 应用程序

原文 在 Visual Studio 2010 中开发和部署 Windows Azure 应用程序 在 Visual Studio 2010 中开发和部署 Windows Azure 应用程序 Jim Nakashima.Hani Atassi 和 Danny Thorpe 将应用程序或服务部署到 Microsoft 云服务平台 Windows Azure 的原因有很多.例如,只为使用的内容付费从而可降低操作和硬件成本.构建几乎能无限缩放的应用程序.巨大的存储容量.地理位置等等,不胜枚举. 只有

windows phone vs2103-vs2013 开发windows phone 引用程序添加程序集的问题

问题描述 vs2013 开发windows phone 引用程序添加程序集的问题 vs2013 开发windows phone 添加引用ToolKit的DLL 报错,错误消息是"The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)" 求大神指点