显示标签为“MFC”的博文。显示所有博文
显示标签为“MFC”的博文。显示所有博文
由于visual c++ 2005 已经包含了GDI+的开发包,所以配置比较简单。

1. 在项目属性中添加GDI+静态链接库
右键项目 点属性,打开项目属性对话框,展开【配置属性】,选择【链接器】下的【输入】,然后在【附加依赖项】中添加"gdiplus.lib",注意要给所有要用的模式都加上(左上角)。

2. 添加头文件
#include<> #include<> 其中afxdtctl.h一般在afxstd.h中包含,需要把#include<>放在其后,重要

3. 使用命名空间
using namespace Gdiplus;

4. 使用GDI+之前,还要记得的初始化
GdiplusStartupInput m_GdiplusStartupInput;
ULONG_PTR m_GdiplusToken;
GdiplusStartup(&m_GdiplusToken, &m_GdiplusStartupInput, NULL);

5. 用完了释放GDI+
GdiplusShutdown(m_GdiplusToken);

关于无法使用new 来创建bitmap或者image对象
解决方法如下:

查询msdn后,发现这是 GDI+的bug,需要改写一个头文件,微软msdn上有下载,http://support.microsoft.com/kb/317799/zh-cn

  1. 方法一 在PreCreateWindow中更改:
    在View::PreCreateWindow(CREATESTRUCT& cs)中加入:

    HBRUSH hbkbrush=CreateSolidBrush(RGB(192,192,192));//创建灰色背景刷
    LPCSTR lpMyOwnClass=AfxRegisterWndClass(CS_HREDRAWCS_VREDRAWCS_OWNDC,0,hbkbrush);//注册新类
    cs.lpszClass=lpMyOwnClass;//修改缺省的类风格

  2. 方法二 在消息处理函数OnEraseBkgnd中贴bmp位图作为背景色

    // TODO: Add your message handler code here and/or call default
    CBitmap bmInvader;
    bmInvader.LoadBitmap(IDB_BITMAP1);
    CBrush brInvader(&bmInvader);
    CRect rcClient;
    GetClientRect(&rcClient);
    pDC->FillRect(&rcClient,&brInvader);
    return true;
    // return CView::OnEraseBkgnd(pDC);


  3. 方法三 在运行时使用SetClassLong更改

    static CBrush brush(RGB(255,0,255));
    SetClassLong(this->m_hWnd,GCL_HBRBACKGROUND,(LONG)(HBRUSH)brush);

见微软帮助http://support.microsoft.com/kb/141921/zh-cn

1.如何初始化显示时不显示子视图
在应用程序类的InitInstance函数中,有这么两句:
// 分析标准外壳命令、DDE、打开文件操作的命令行
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
//添加下面这句话,即可
cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;


后续待添加:)


调色板概述

每个应用程序都有自己的调色板,使用调色板时要先向系统申请,调色板分为前台调色板和后台调色板,windows为优先级高的程序分配前台调色板.我们经常会发现当启动一个大一点的程序时,桌面和其他应用程序的颜色变得粗糙起来,就是因为其他应用程序的调色板正在转为后台调色板.

Windows系统内部保留了一个20种颜色的调色板,用来显示窗口,菜单等通用界面每个设备上下文都拥有一个逻辑调色板,如果要使用内部系统调色板(20种颜色)之外的颜色,则应该创建一个新的逻辑调色板并将其选入到设备上下文中.再把设备上下文中的逻辑调色板实现到系统调色板中,新的颜色才能实现.

在逻辑调色板被实现到系统调色板时,Windows会建立一个调色板映射表,当设备上下文用逻辑调色板中的颜色绘图时,GDI绘图函数会查询调色板映射表以把像素值从逻辑调色板的索引转换成系统调色板的索引.

创建调色板BOOL CreatePalette(LPLOGPALETTE lpLogPalette );

其中lpLogPalette是一个指向LOGPALETTE 结构的指针
typedef struct tagLOGPALETTE {
WORD palVersion; //windows版本号,一般是0x300
WORD palNumEntries; //调色板中颜色表项的数目
PALETTEENTRY palPalEntry[1]; //每个表项的颜色和使用方法
} LOGPALETTE;

typedef struct tagPALETTEENTRY {
BYTE peRed; //红(0-255)
BYTE peGreen;// 绿
BYTE peBlue; //蓝
BYTE peFlags; //一般为0
} PALETTEENTRY;

上面只是建立了一个逻辑调色板,而逻辑调色板只是一张孤立的颜色表,并不能对系统产生影响,所以要使用调色板还需要下面这些函数CPalette* SelectPalette(CPalette* pPalette,BOOL bForceBackground );
这个函数用来将一个调色板载入设备上下文,第一个参数是一个调色板指针,第二个参数用来指定调色板作为前景色还是背景色使用,为TURE时,作为背景色使用,为FALSE时,当窗口是活动窗口或活动窗口的子窗口是,调色板将做为前景色使用,否则做为背景色来使用.如果使用调色板的是一个内存设备上下文,则该参数被忽略.UINT RealizePalette( );该函数把设备上下文中的逻辑调色板实现到系统调色板中, 函数的返回值表明调色板映射表中有多少项被改变了
这两个函数的使用如下:
CPalette *pOldPalette ;
CWindowDC dc(this) ;
pOldPalette=dc.SelectPalette(&pal, FALSE) ;
dc.RealizePalette() ;
dc.SelectPalette(pOldPalette, FALSE) ;

如果某一个窗口要显示特殊的颜色,那么一般应该在处理WM_PAINT消息时实现自己的逻辑调色板,也就是说,在OnPaint或OnDraw函数中重绘以前,要调用SelectPalette和RealizePalette,如果窗口显示的颜色比较重要,则要在调用SelectPalette时指定bForceBackground参数为FALSE.
创建调色板的一般步骤:
1 建立一个LOGPALETTE结构和PALETTEENTRY数组
2 对PALETTEENTRY数组进行赋值,即创建调色板颜色表
3 建立CPalette对象并使用CreatePalette函数初始化调色板对象
4 使用SelectPalette函数将设备描述表和调色板联系起来
5 使用CDC中的RealizePalette函数使调色板生效
为了协调各个窗口对系统调色板的使用,Windows在必要的时候会向顶层窗口和重绘窗口发送消息WM_QUERYNEWPALETTE和WM_PALETTECHANGED.当某一顶层或重叠窗口被激活时,会收到WM_QUERYNEWPALETTE消息,在窗口的创建之处也会收到该消息,该消息先于WM_PAINT消息到达窗口,如果活动窗口要使用特殊的颜色,则在收到该消息时应该实现自己的逻辑调色板并重绘窗口.

原作者信息
http://hi.baidu.com/liuhuishan/blog/item/245c774ef477ff01b3de0524.html

滑动条控制(Slider Control)也叫轨道条控制,其主要是用一个带有轨道和滑标的小窗口以及窗口上的刻度,来让用户选择一个离散数据或一个连续的数值区间。通过鼠标或键盘来进行数据的选择操作,这在WIN98/95中的很多应用程序中都可以看到,如控制面板中的鼠标等,滑动条既可以是水平方式的也可以是垂直方式的。滑动条控制的风格如下:
TBS_HORZ 滑动条是水平方向的 TBS_VERT 滑动条是垂直方向的
TBS_LEFT 滑动条位于窗口左侧 TBS_RIGHT 滑动条位于窗口右侧
TBS_TOP 滑动条位于窗口顶部 TBS_BOTTOM 滑动条位于窗口底部
TBS_BOTH 滑动条位于窗口两侧 TBS_AUTOTICKS滑动条具有刻度,默认
TBS_NOTICKS 滑动条不具有刻度
  滑动条的刻度条在每一个数值位置显示一个刻度标记,如果在滑动条上显示某一数值选择区间,则应使用风格TBS_ENABLESELRANGE,此时选择区间两个不再是刻度标记,而是一个小的三角形符号。另外,使用风格TBS_NOTHUMB会使滑标消隐起来。
  滑动条控制在MFC类库中被封装为CSliderCtrl控制,其主要操作是设置刻度范围、绘制刻度标记、设置选择范围和当前滑标位置等。当用户进行交互操作时,滑动条控制将向其父窗口发送消息WM_HSCROLL,所以在应用程序中应重载父窗口的OnHScroll()成员函数,以便对消息进行正确处理系统发送的通知代码、滑标位置和指向CSliderCtrl对象的指针等。由于考虑到和水平卷动杆公用同一个成员函数,OnHScroll()函数参数表中的指针变量被定义为CScrollBar*类型,由于实际上消息是由滑动条产生的,所以在程序中必须把这个指针变量强制转换为CSliderCtrl*类型。滑动条和卷动杆的消息代码和含义都非常类似如TB_BOTTOM等,所以这种处理方法比较合理。SetRange()函数用来设置范围,SetPos()函数用来设置当前位置。
(二)滑动条控制的对象结构
  滑动条控制的建立方法
   CsliderCtrl &SliderCtrl 建立滑动条控制对象结构;Create 建立滑动条控制对象并绑定对象
   滑动条控制类CSliderCtrl::Create的调用格式如下:
  BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );
  其中参数dwStyle用来确定滑动条控制风格;参数rect用来确定滑动条控制的大小和位置;参数pParentWnd用来确定滑动条控制的父窗口指针;参数nID用来确定滑动条控制的控制符ID值。
  2、滑动条控制的类属性
  滑动条控制对象的类属性包括取得滑动条大小GetLineSize、设置滑动条大小SetLineSize、取得滑动条页大小GetPageSize、设置滑动条页大小SetPageSize、取得滑动条最大位置GetRangeMax、取得滑动条最小位置GetRangeMin、取得滑动条范围GetRange、设置滑块最小位置SetRangeMin、设置滑块最大位置SetRangeMax、设置滑动条范围SetRange、取得滑块当前位置GetSelection、设置滑块当前位置SetSelection、取得滑动条当前位置GetPos和设置滑动条当前位置SetPos等。
  3、滑动条控制的操作方法
  滑动条控制的操作方法包括清除滑动条当前选择ClearSel、验证滑动条当前位置是否在最大最小位置之间VerifyPos和清除当前刻度标志ClearTics。
  滑动条控制的应用技巧示例
  1、利用应用程序向导AppWizard生成基于对象框的应用程序CSlidDlg;
  2、在对话框中设置滑动条控制,其ID为IDC_SLIDER;
  3、在对话框初始代码中增加控制的范围和位置:
  (1)在SlidDlg.h中设置数据成员,用来表示滑动条的当前值:
//SlidDlg.h
class CSlidDlg:public Cdialog
{ ......//其它代码
public:
int m_nCur;
......//其它代码
}
(2)在SlidDlg.cpp中设置初始状态
BOOL CSlidDlg::OnInitDialog()
{ Cdialog::OnInitDialog();
......//其它代码
//TODO:Add extra initialization here
CSliderCtrl *pSlidCtrl=(CSliderCtrl*)GetDlgItem(IDC_SLLIDER);
pSlidCtrl->SetRange(1,5,TRUE);//设置滑动条范围
pSlidCtrl->SetPos(2);//设置滑动条位置
......//其它代码
return TRUE;
}
(3)完善滑动条的消息处理,利用类向导ClassWizard增加对话框窗口的WM_HSCROLL消息处理函数,并取得滑标所指位置值:
void CSlidDlg::OnHScroll(UINT nSBCode,UINT nPos,CScrollBar *pScrollBar)
{ //TODO:Add your message handler?
Cdialog::OnHScroll(nSBCode,nPos,pScrollBar);
CSliderCtrl *pSlidCtrl=(CSliderCtrl*)GetDlgItem(IDC_SLLIDER);
m_nCur=pSlidCtrl->GetPos();//取得当前位置值
}
以前都是自己生成打开的对话框,定义代码如下
CFileDialog dlg(TRUE,
"rtf",
"*.rtf",
OFN_HIDEREADONLY OFN_OVERWRITEPROMPT,
"*.rtf",
this);
dlg.m_ofn.lpstrTitle="请选择文本文件";
char szCurDir[255];
GetCurrentDirectory(255,szCurDir);
dlg.m_ofn.lpstrInitialDir=CString(szCurDir);
if(IDOK!=dlg.DoModal())
return FALSE;

如果用系统的重载,可以省掉写这写代码,而且重载的打开对话框的功能和windows一模一样,比较健全。
但是扩展名匹配就比较麻烦,以前只知道要在向导中填好。

那么万一忘了呢?
还可以这样修改

修改字符串资源
IDR_MAINFRAME为
myTitle\n\n新文件\nmyFile文件 (*.txt)\n.txt\nmyFileID\nDoc Document

关键是中间带.txt的两部分

恩 这个就很方便了:) MFC就是适合傻瓜化操作
关于IDR_MAINFRAME的详细定义可以查看