由主窗口new出来的非模态对话框,在释放的时候一定要注意!
1.需要重写当前窗口的OnCancel()
虚函数,直接调用DestroyWindow()
函数,然后删掉基类的OnCancel()
调用。
2.重写当前窗口的OnNCDestroy()
虚函数,在基类执行完毕后使用 delete this
彻底释放内存空间。
void HT_MenuSPSDlg::OnNcDestroy() { CDialogEx::OnNcDestroy(); // TODO: TRACE(_T("OnNcDestroy!\n")); delete this; } void HT_MenuSPSDlg::OnCancel() { // TODO: TRACE(_T("OnCancel!\n")); DestroyWindow(); }
详细的解释:
一个MFC窗口对象包括两方面的内容:一是窗口对象封装的窗口,即存放在m_hWnd成员中的HWND(窗口句柄),二是窗口对象本身是一个C++对象。要删除一个MFC窗口对象,应该先删除窗口对象封装的窗口,然后删除窗口对象本身。 删除窗口最直接方法是调用CWnd::DestroyWindow或::DestroyWindow,前者封装了后者的功能。前者不仅会调用后者,而且会使成员m_hWnd保存的HWND无效(NULL)。如果DestroyWindow删除的是一个父窗口或拥有者窗口,则该函数会先自动删除所有的子窗口或被拥有者,然后再删除父窗口或拥有者。在一般情况下,在程序中不必直接调用DestroyWindow来删除窗口,因为MFC会自动调用DestroyWindow来删除窗口。例如,当用户退出应用程序时,会产生WM_CLOSE消息,该消息会导致MFC自动调用CWnd::DestroyWindow来删除主框架窗口,当用户在对话框内按了OK或Cancel按钮时,MFC会自动调用CWnd::DestroyWindow来删除对话框及其控件。
对于一个在堆中动态创建的窗口对象,其生命期却是任意长的。所以可能会产生这样的疑问,为什么有些程序用new创建了一个窗口对象,却未显式的用delete来删除它呢?问题的答案就是有些MFC窗口对象具有自动清除的功能。 如前面讲述非模态对话框时所提到的,当调用CWnd::DestroyWindow或::DestroyWindow删除一个窗口时,被删除窗口的PostNcDestroy成员函数会被调用。缺省的PostNcDestroy什么也不干,但有些MFC窗口类会覆盖该函数并在新版本的PostNcDestroy中调用delete this来删除对象,从而具有了自动清除的功能。此类窗口对象通常是用new操作符创建在堆中的,但程序员不必操心用delete操作符去删除它们,因为一旦调用DestroyWindow删除窗口,对应的窗口对象也会紧接着被删除。 对于在堆中动态创建了的非自动清除的窗口对象,必须在窗口被删除后,显式地调用delete来删除对象(一般在拥有者或父窗口的析构函数中进行).对于具有自动清除功能的窗口对象,只需调用CWnd::DestroyWindow即可删除窗口和窗口对象。注意,对于在堆中创建的窗口对象,不要在窗口还未关闭的情况下就用delete操作符来删除窗口对象。
摘自《Visual C++ 数字图像处理技术详解》(刘海波等编著)
3个基本颜色:红R、绿G、蓝B
3个基本特性参数:亮度、色调、饱和度。色调与饱和度合称为色度。
当把红、绿、蓝三色光混合时,通过改变三者各自的强度比例可得到各种色调和饱和度的颜色。
HSI颜色模式是从人的视觉系统出发,用色调、饱和度、亮度来描述色彩。通常把色调和饱和度通称为色度,用来表示颜色的类别与深浅程度。由于人类的视觉对亮度的敏感程度远强于对颜色浓淡的敏感程度,为了便于色彩的处理和识别,视觉系统经常采用HSI颜色模式。HSI颜色模式可以大大简化图像分析和处理的工作量。
HSI颜色模式和RGB颜色模式只是同一个物理量的不同表示法,因此它们之间存在着转换关系。
色调(Hue):物体传导或反射的波长。取0°~360°的数值来衡量。
饱和度(Saturation):色彩的强度或纯度。代表灰色与色调的比例,并以0%(灰色)到100%(完全饱和)来衡量。
亮度(Intensity):颜色的相对明暗度。以0%(黑色)到100%(白色)的百分比来衡量。
Lab颜色模式、YUV颜色模式、CMYK颜色模式等。
Windows采用24位真彩色,红、绿、蓝三原色分别用8Bit来表示。其SDK提供了一个名为RGB的宏将一组RGB颜色值转化为24位颜色值。
COLORREF RGB(BYTE bRed, BYTE bGreen, BYTE bBlue)
COLORREF并不是24位,而是32位无符号长整型变量。其高8位作为保留用于与将来的系统兼容。
Visual C++中,MFC定义了CPalette类来对调色板进行操作。
Windows中的位图操作与调色板密切相关。Windows使用两种不同的位图,即设备相关位图DDB和设备无关位图DIB。DIB位图文件中包含该位图的逻辑调色板的颜色表,其像素值是该调色板中的颜色索引值。DDB位图文件中不包含调色板信息,其像素值是该系统调色板中的颜色索引值。DIB与DDB的主要区别在于DIB包含一个名为RGBQUAD的结构,描述了DIB位图的颜色表。
Win32 SDK使用调色板句柄HPALETTE来表示调色板,HPALETTE与CPalette对象的相互转换由下面的函数实现:
CPalette::FromHandle
CPalette::GetSafeHandle
计算机内的数字图像通常用由采样点的值所组成的矩阵来表示。每一个采样点单元叫做一个像素(pixel)。由于数字图像格式不同,图像文件一般具有不同的扩展名。最常见的图像格式是位图格式,其文件名以BMP为扩展名。
位图文件头结构 BITMAPFILEHEADER
位图信息头结构 BITMAPINFOHEADER
位图颜色表 RGBQUAD
位图像素数据
typedef struct tagBITMAPFILEHEADER { WORD bfType; //位图文件的类型,必须为"BM",即0x424D,才是Windows位图文件 DWORD bfSize; //整个BMP文件的大小 WORD bfReserved1; //位图文件保留字,必须为0; WORD bfReserved2; //位图文件保留字,必须为0; DWORD bfOffBits; //位图数据起始位置,以相对于文件头的偏移量表示,以字节为单位 } BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER{ DWORD biSize; //本结构所占字节数 LONG biWidth; //位图的宽度,以像素为单位 LONG biHeight; //位图的高度,以像素为单位 WORD biPlanes; //目标设备的级别,必须为1 WORD biBitCount; //每个像素所需的位数,1:双色,4:16色,8:256色,24:真彩色 DWORD biCompression; //位图压缩类型,0:不压缩,1:B1_RLE8压缩类型,2:B1_RLE4压缩类型 DWORD biSizeImage; //位图的大小 LONG biXPelsPerMeter; //位图的水平分辨率,以像素/米为单位 LONG biYPelsPerMeter; //位图的垂直分辨率,以像素/米为单位 DWORD biClrUsed; //位图实际使用的颜色表中的颜色数 DWORD biClrImportant; //位图显示过程中重要的颜色数 } BITMAPINFOHEADER;
8位位图文件中,每个像素占8位,可表示256种颜色,8位位图文件含有颜色表,而24位真彩色位图文件中不含颜色表。颜色表用于说明位图中的颜色,它有若干个表项,每个表项是一个RGBQUAD类型的结构,定义一种颜色。
typedef struct tagRGBQUAD { BYTE rgbBlue; //蓝色的亮度(值范围 0~255) BYTE rgbGreen; //绿色的亮度(值范围 0~255) BYTE rgbRed; //红色的亮度(值范围 0~255) BYTE rgbReserved; //保留,必须为0 } RGBQUAD;
位图信息头和颜色表组成位图信息 BITMAPINFO
typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; //位图信息头 RGBQUAD bmiColors[1]; //颜色表 } BITMAPINFO;
位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:
当biBitCount=1时,8个像素占1个字节;
当biBitCount=4时,2个像素占1个字节;
当biBitCount=8时,1个像素占1个字节;
当biBitCount=24时,1个像素占3个字节;
Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充。
TIFF(Tag Image File Format,标签图像文件格式)文件最初由Aldus公司与微软公司为PostScript打印联合开发。
TIFF最初的设计目的是为了1980年代中期桌面扫描仪厂商达成一个公用的扫描图像文件格式,而不是每个厂商使用自己专有的格式。在刚开始的时候,TIFF只是一个二值图像格式,随着扫描仪的功能越来越强大,并且桌面计算机的磁盘空间越来越大,TIFF逐渐开始支持灰阶图像和彩色图像。
GIF(Graphics Interchange Format,图像交换格式),由美国CompuServe公司在1987年提出,最初的目的是希望每个BBS使用者能够通过GIF图像文件轻易存储并交换图像数据。
GIF采用了一种改进LZW压缩算法,通常称之为GIF-LZW压缩算法,是一种无损的压缩算法,压缩效率比较高,并且GIF支持在一幅GIF文件中存放多幅彩色图像,并且可以按照一定的顺序和时间间隔将多幅图像依次读出并显示在屏幕上,形成一种简单的动画效果。
GIF支持24位色彩,即最多可表示256种颜色,图像大小最多是64K*64K像素。
JPEG(Joint Photographic Experts Group,联合图像专家组)是由一个软件开发联合会组织制定,是一种有损压缩格式。JPEG的压缩技术十分先进,它用有损压缩的方式去除冗余数据,在获得极高压缩率的同时能展现十分丰富生动的图像,是目前最常用的图像文件格式。
RAW文件格式是CMOS或者CCD图像感应器将捕捉到的光源信号转换为数字信号的原始数据。RAW文件是一种记录了数码相机传感器的原始信息,同时记录了由相机拍摄所产生的一些元数据(Metadata,如ISO的设置、快门速度、光圈值、白平衡等)的文件。RAW是未经处理、也未经压缩的格式,可以把RAW概念化为“原始图像编码数据”或更形象的称为“数字底片”。
DIB位图可以在不同的机器或系统中显示位图所固有的图像。与设备相关位图DDB相比,DIB是一种外部的位图格式,经常存储为以BMP为后缀的位图文件(有时也以DIB为后缀)。DIB位图还支持图像数据的压缩。
以下为Win32 SDK支持的一些重要的DIB操作函数:
函数 | 功能描述 |
---|---|
GetDIBits | 从DDB中获取位图的图像位,用于将DDB转换为DIB格式 |
SetDIBits | 设置DIB位图的图像位,用于将DIB转换为DDB格式 |
CreateDIBitmap | 用指定的DIB来创建DDB,并用DIB信息初始化位图的图像位 |
SetDIBitmap | 直接将DIB位图的图像位输出到设备,用于显示DIB |
StretchDIBits | 将DIB位图映射输出到设备的一个矩形区域,位图可能被缩放 |
CreateDIBPatternBrush | 用DIB位图来创建模式画刷 |
CreateDIBSection | 创建一个可直接写入的DIB |
GetDIBColorTable | 获取DIB颜色表 |
SetDIBColorTable | 设置DIB颜色表 |
相关函数说明:
FrozenSky’s CDib_Ex
https://github.com/FrozenSky7124/Project_MSVS/tree/master/C++/FrozenSky/DLL_CDib
// EditControl文本垂直居中 RECT editRect; GetDlgItem(IDC_EDIT_IP)->GetClientRect(&editRect); OffsetRect(&editRect, 0, 4); GetDlgItem(IDC_EDIT_IP)->SendMessage(EM_SETRECT, 0, (LPARAM)&editRect);
需要注意:EditControl控件必须启用多行模式
Sets the formatting rectangle of a multiline edit control. The formatting rectangle is the limiting rectangle into which the control draws the text. The limiting rectangle is independent of the size of the edit control window.
This message is processed only by multiline edit controls. You can send this message to either an edit control or a rich edit control.
Rich Edit 2.0 and later: Indicates whether lParam specifies absolute or relative coordinates. A value of zero indicates absolute coordinates. A value of 1 indicates offsets relative to the current formatting rectangle. (The offsets can be positive or negative.)
Edit controls and Rich Edit 1.0: This parameter is not used and must be zero.
A pointer to a RECT structure that specifies the new dimensions of the rectangle. If this parameter is NULL, the formatting rectangle is set to its default values.
This message does not return a value.
在上一篇Blog中,已经详细记录了如何在Ubuntu 16.04上搭建Ruby & Jekyll环境!现在就要开始用Jekyll搞些事情啦!(GitHubPage瑟瑟发抖…
简书上的GitHubPage攻略:https://www.jianshu.com/p/85ca31174488
本文所使用的Jekyll主题:https://github.com/Gaohaoyang/gaohaoyang.github.io
~$ git clone https://github.com/Gaohaoyang/gaohaoyang.github.io.git
–新建站点目录
~$ jekyll new GitHubPage_Root
–进入站点目录
~$ cd ./GitHubPage_Root
–启动Jekyll服务
~$ jekyll serve
Deprecation: The 'gems' configuration option has been renamed to 'plugins'. Please update your config file accordingly.
Dependency Error: Yikes! It looks like you don't have jekyll-paginate or one of its dependencies installed. In order to use Jekyll as currently configured, you'll need to install this gem. The full error message from Ruby is: 'cannot load such file -- jekyll-paginate' If you run into trouble, you can find helpful resources at https://jekyllrb.com/help/!
jekyll 3.7.2 | Error: **jekyll-paginate**
~$ gem install jekyll-paginate
~$ jekyll serve
Configuration file: /home/frozensky/GitHubPage_Root/_config.yml
Deprecation: The ‘gems’ configuration option has been renamed to ‘plugins’. Please update your config file accordingly.
Source: /home/frozensky/GitHubPage_Root
Destination: /home/frozensky/GitHubPage_Root/_site
Incremental build: disabled. Enable with –incremental
Generating…
done in 1.325 seconds.
Auto-regeneration: enabled for ‘/home/frozensky/GitHubPage_Root’
Server address: http://127.0.0.1:4000/
Server running… press ctrl-c to stop.
至此,本地调试用的Jekyll环境搭建完成。
具体步骤见参考资料。
注意!GitHub仓库的名称必须为:[YourAccountName].github.io
~$ git clone git@github.com:FrozenSky7124/FrozenSky7124.github.io.git
复制本地网站根目录的文件到Git本地库
创建.gitignore文件,并添加需要忽略的文件和目录
这里我们需要在该文件中添加”_site”,这个目录是本地Jekyll调试环境所生成的静态网页文件,不需要上传到GitHub仓库中。
注意!首次操作可能提示缺少密钥,具体解决方法参考GitHub官方说明。
~$ git remote add origin git@github.com:FrozenSky7124/FrozenSky7124.github.io.git
~$ git add .
~$ git commit -m “XXXXXXXX”
稍等片刻,GitHubPage服务器就会将我们上传的文件进行转换,变成静态网页。
通过[YourAccountName].github.io 就可以正常访问了。
Jekyll官方中文文档:https://www.jekyll.com.cn/docs/installation/
RVM实用指南:https://ruby-china.org/wiki/rvm-guide
RVM是一个命令行工具,可以提供一个便捷的多版本Ruby环境的管理和切换。笔者曾使用Ubuntu的 apt-get 命令安装Ruby,出现了未知的历史遗留问题,尝试多种方法均无解。最终使用RVM安装Ruby最新版本才解决问题…
~$ gpg –keyserver hkp://keys.gnupg.net –recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
~$ curl -sSL https://get.rvm.io | bash -s stable
To start using RVM you need to run “source /home/frozensky/.rvm/scripts/rvm”
~$ source /home/frozensky/.rvm/scripts/rvm
~$ rvm -v
~$ rvm requirement
~$ rvm install 2.5.0
~$ rvm use 2.5.0 –default
~$ ruby -v
~$ gem update –system ~$ gem -v
~$ gem sources –add https://gems.ruby-china.org/ –remove https://rubygems.org/
~$ gem sources –list
Jekyll可以将纯文本转化为静态网站和博客,支持Markdown,Liquid,HTML,CSS,有多种多样的个性主题库可供选择。
相比Wordpress架构,笔者认为Jekyll更加简洁高效,并且Jekyll可以和GitHub Page巧妙结合在一起,使用GitHub仓库进行文章管理和版本控制。
~$ sudo gem install jekyll
~$ sudo gem install rdiscount
~$ jekyll –version
/usr/local/lib/site_ruby/2.3.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem jekyll (>= 0.a) with executable jekyll (Gem::GemNotFoundException)
from /usr/local/lib/site_ruby/2.3.0/rubygems.rb:308:in `activate_bin_path'
from /usr/local/bin/jekyll:23:in `<main>'
~$ gem install rack
~$ gem install jekyll