日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MFC使用GDI+编程设置

發布時間:2025/3/15 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MFC使用GDI+编程设置 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

VC2005“項目/*屬性”菜單項,打開項目的屬性頁窗口,先選“所有配置”,再選“配置屬性/鏈接器/輸入”項,在右邊上部的“附加依賴項”欄的右邊,鍵入GdiPlus.lib 后按“應用”鈕,最后按“確定”鈕關閉對話框。

在需要用到GDI+的文件頭加上下面兩句
#include <gdiplus.h>
using namespace Gdiplus;


在應用程序類應用程序類(CGDIPlusDemoApp) 頭文件中聲明一個成員變量:
ULONG_PTR m_gdiplusToken;??? // ULONG PTR 為int64 類型

并在該類的初始化函數CGDIPlusDemoApp::InitInstance() 中加入以下代碼來對GDI+進行初始化:

GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);

注意:這兩個語句必須加在應用程序類的InitInstance函數中的
CWinApp:: InitInstance ();
語句之前,不然以后會造成視圖窗口不能自動重畫、程序中不能使用字體等等一系列問題。


還要在CGDIPlusDemoApp::ExitInstance() 函數(重寫)中加入以下代碼來關閉GDI +:
GdiplusShutdown(m_gdiplusToken);

上面是所需步驟..


MFC使用GDI+編程基礎

封裝在GDI+ API中的各種C++類、函數、常量、枚舉和結構,都被定義在Gdiplus.h頭文件所包含的一系列頭文件中。所以,采用MFC進行GDI+編程,必須包含Gdiplus.h頭文件。

封裝在GDI+類中方法,最后都需要調用GDI+平面API中的相關底層函數,才能完成實際的操作。所以,為了運行GDI+應用程序,在操作系統平臺中,必須安裝動態鏈接庫Gdiplus.dll。

該動態鏈接庫所對應的靜態庫文件為GdiPlus.lib,而且它不是C++和MFC的缺省鏈接庫。所以,必須在項目設置,添加該庫作為鏈接器輸入的附加依賴項。

因為在Gdiplus.h頭文件中,將所有的GDI+的類、函數、常量、枚舉和結構等都定義在了命名空間Gdiplus中。所以,一般在GDI+程序中,都必須使用如下的命名空間聲明:

using namespace Gdiplus;

例如:

#include <gdiplus.h>

using namespace Gdiplus;

……

1)GdiPlus.h
/*********************************************************************/

* Copyright (c) 1998-2001, Microsoft Corp. All Rights Reserved.

* Module Name:

*?? Gdiplus.h

* Abstract:

*?? GDI+ public header file

/*********************************************************************/

#ifndef _GDIPLUS_H

#define _GDIPLUS_H

struct IDirectDrawSurface7;

typedef signed?? short?? INT16;

typedef unsigned short UINT16;

#include <pshpack8.h>?? // set structure packing to 8

namespace Gdiplus

{

??? namespace DllExports {

??????? #include "GdiplusMem.h"

??? };

??? #include "GdiplusBase.h"

??? #include "GdiplusEnums.h"

??? #include "GdiplusTypes.h"

??? #include "GdiplusInit.h"

??? #include "GdiplusPixelFormats.h"

??? #include "GdiplusColor.h"

??? #include "GdiplusMetaHeader.h"

??? #include "GdiplusImaging.h"

??? #include "GdiplusColorMatrix.h"

??? #include "GdiplusGpStubs.h"

??? #include "GdiplusHeaders.h"

??? namespace DllExports {

??????? #include "GdiplusFlat.h"

??? };

??? #include "GdiplusImageAttributes.h"

??? #include "GdiplusMatrix.h"

??? #include "GdiplusBrush.h"

??? #include "GdiplusPen.h"

??? #include "GdiplusStringFormat.h"

??? #include "GdiplusPath.h"

??? #include "GdiplusLineCaps.h"

??? #include "GdiplusMetafile.h"

??? #include "GdiplusGraphics.h"

??? #include "GdiplusCachedBitmap.h"

??? #include "GdiplusRegion.h"

??? #include "GdiplusFontCollection.h"

??? #include "GdiplusFontFamily.h"

??? #include "GdiplusFont.h"

??? #include "GdiplusBitmap.h"

??? #include "GdiplusImageCodec.h"

}; // namespace Gdiplus

#include <poppack.h>??? // pop structure packing back to previous state

#endif // !_GDIPLUS_HPP

2)GDI+的初始化與清除
為了在MFC應用程序中使用采用C++封裝的GDI+ API,必須在MFC項目的應用程序類中,調用GDI+命名空間中的GDI+啟動函數GdiplusStartup和GDI+關閉函數GdiplusShutdown,來對GDI+進行初始化(裝入動態鏈接庫Gdiplus.dll,或鎖定標志+1)和清除(卸載動態鏈接庫Gdiplus.dll,或鎖定標志-1)工作。它們一般分別在應用程序類的InitInstance和ExitInstance重載成員函數中調用。

函數GdiplusStartup和GdiplusShutdown,都被定義在GdiplusInit.h頭文件中:

Status WINAPI GdiplusStartup(

??? OUT ULONG_PTR *token,

??? const GdiplusStartupInput *input,

??? OUT GdiplusStartupOutput *output);

void GdiplusShutdown(ULONG_PTR token);

其中:

<!--[if !supportLists]-->l???? <!--[endif]-->類型ULONG_PTR,是用無符號長整數表示的指針,被定義在basetsd.h頭文件中:

typedef _W64 unsigned long ULONG_PTR;

輸出參數token(權標),供關閉GDI+的函數使用,所以必須設置為應用程序類的成員變量(或全局變量,不提倡)。

<!--[if !supportLists]-->l???? <!--[endif]-->結構GdiplusStartupInput和GdiplusStartupOutput,也都被定義在GdiplusInit.h頭文件中:

struct GdiplusStartupInput {

??? UINT32 GdiplusVersion;??????????? // Must be 1

??? DebugEventProc DebugEventCallback; // Ignored on free builds

??? BOOL SuppressBackgroundThread;?? // FALSE unless you're prepared to call

?????????????????????????????????????? // the hook/unhook functions properly

??? BOOL SuppressExternalCodecs;????? // FALSE unless you want GDI+ only to use

?????????????????????????????????????? // its internal image codecs.

??? GdiplusStartupInput(

??????? DebugEventProc debugEventCallback = NULL,

??????? BOOL suppressBackgroundThread = FALSE,

??????? BOOL suppressExternalCodecs = FALSE) {

??????? GdiplusVersion = 1;

??????? DebugEventCallback = debugEventCallback;

??????? SuppressBackgroundThread = suppressBackgroundThread;

??????? SuppressExternalCodecs = suppressExternalCodecs;

??? }

};

struct GdiplusStartupOutput {

??? NotificationHookProc NotificationHook;

??? NotificationUnhookProc NotificationUnhook;

};

<!--[if !supportLists]-->n????????????? <!--[endif]-->GDI+啟動輸入結構指針參數input,一般取缺省構造值即可,即(設:無調試事件回調過程、不抑制背景線程、不抑制外部編解碼):

input = GdiplusStartupInput(NULL, FALSE, FALSE);

<!--[if !supportLists]-->n????????????? <!--[endif]-->GDI+啟動輸出結構指針參數output,一般不需要,取為NULL即可。

?

注意,采用MFC進行GDI+ API編程時,在使用任何GDI+的功能調用之前,必須先調用GDI+啟動函數GdiplusStartup來進行初始化GDI+的工作;在完成所有的GDI+功能調用之后,必須調用GDI+關閉函數GdiplusShutdown來進行清除GDI+的工作。

例如:(創建一個名為GdipDraw的MFC單文檔應用程序項目,在項目屬性中添加GdiPlus.lib庫作為鏈接器輸入的附加依賴項)

// GdipDraw.h

……

class CGdipDrawApp : public CWinApp

{

public:

?????? CGdipDrawApp();

?????? ULONG_PTR m_gdiplusToken;

?????? ……

};

?

// GdipDraw.cpp

……

#include <gdiplus.h>

using namespace Gdiplus;

……

BOOL CGdipDrawApp::InitInstance()

{

?????? // 如果一個運行在 Windows XP 上的應用程序清單指定要

?????? // 使用 ComCtl32.dll 版本 6 或更高版本來啟用可視化方式,

?????? //則需要 InitCommonControlsEx()。否則,將無法創建窗口。

?????? INITCOMMONCONTROLSEX InitCtrls;

?????? InitCtrls.dwSize = sizeof(InitCtrls);

?????? // 將它設置為包括所有要在應用程序中使用的

?????? // 公共控件類。

?????? InitCtrls.dwICC = ICC_WIN95_CLASSES;

?????? InitCommonControlsEx(&InitCtrls);

?

?????? /*注意:下面這兩個語句必須加在CWinApp:: InitInstance ();語句之前,不然以后會造成視圖窗口不能自動重畫、程序中不能使用字體等等一系列問題。*/

?????? GdiplusStartupInput gdiplusStartupInput;

?????? GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);

?

?????? CWinApp::InitInstance();

?????? ……

}

……

int CGdipDrawApp::ExitInstance() // 該函數是自己利用屬性窗口,添加的重寫函數

{

?????? // TODO: 在此添加專用代碼和/或調用基類

?????? GdiplusShutdown(m_gdiplusToken);

?????? return CWinApp::ExitInstance();

}

3)幾何輔助類
在GDI+ API中,定義了許多繪圖的輔助類,常用的有點、大小和矩形等幾何類。它們都是沒有基類的獨立類,被定義在頭文件GdiplusTypes.h中。下面逐個進行介紹:

(1)Point[F](點)
GDI+中,有兩種類型的點:整數點(對應于Point類)和浮點數點(對應于PointF類)。下面分別加以介紹:

<!--[if !supportLists]-->l???? <!--[endif]-->整數點類Point:

class Point {

public:

?? Point() {X = Y = 0;}

?? Point(const Point &point) {X = point.X; Y = point.Y;}

?? Point(const Size &size) {X = size.Width; Y = size.Height;}

?? Point(INT x, INT y) {X = x; Y = y;}

?? Point operator+(const Point& point) const {return Point(X + point.X, Y + point.Y);}

?? Point operator-(const Point& point) const {return Point(X - point.X, Y - point.Y);}

?? BOOL Equals(const Point& point) {return (X == point.X) && (Y == point.Y);}

public:

??? INT X; // 大寫X、Y

??? INT Y;

};

其中:

typedef int INT; // 4字節有符號整數(windef.h)

注意,這里的點與GDI的區別:

POINT和CPoint:{x; y;} // 小寫x、y

?

<!--[if !supportLists]-->l???? <!--[endif]-->浮點數點類PointF:

class PointF {

public:

?? PointF() {X = Y = 0.0f;}

?? PointF(const PointF &point) {X = point.X; Y = point.Y;}

?? PointF(const SizeF &size) {X = size.Width; Y = size.Height;}

?? PointF(REAL x, REAL y) {X = x; Y = y;}

?? PointF operator+(const PointF& point) const {return PointF(X + point.X,Y + point.Y);}

?? PointF operator-(const PointF& point) const {

?????? return PointF(X - point.X, Y - point.Y);

?? }

?? BOOL Equals(const PointF& point) {

?????? return (X == point.X) && (Y == point.Y);

?? }

public:

??? REAL X;

??? REAL Y;

};

其中:

typedef float REAL; // 4字節浮點數(GdiplusTypes.h)

?

注意,浮點數版的幾何對象和繪圖函數,是GDI+新增的功能,這些在各種工程技術領域都非常有用。因為一般的實際圖形設計,都是基于實數坐標的。包括機械(機床/汽車/輪船/飛機等)、建筑(房屋/橋梁/道路/堤壩等)和圖形動畫設計(形狀/物體/人物/背景/軌跡等)等設計,都必須使用浮點參數和坐標系。

(2)Size[F](大小)
GDI+中,也有兩種類型的大小(尺寸):整數大小(對應于Size類)和浮點數大小(對應于SizeF類)。下面分別加以介紹:

<!--[if !supportLists]-->l???? <!--[endif]-->整數大小類Size:

class Size {

public:

??? Size() {Width = Height = 0;}

??? Size(const Size& size) {Width = size.Width; Height = size.Height;}

??? Size(INT width, INT height) {Width = width; Height = height;}

??? Size operator+(const Size& sz) const {

??????? return Size(Width + sz.Width, Height + sz.Height);

?????? }

??? Size operator-(const Size& sz) const {

??????? return Size(Width - sz.Width, Height - sz.Height);

??? }

??? BOOL Equals(const Size& sz) const {

??????? return (Width == sz.Width) && (Height == sz.Height);

??? }

??? BOOL Empty() const {return (Width == 0 && Height == 0);}

public:

??? INT Width; // 不是cx和cy

??? INT Height;

};

注意,這里的大小與GDI的區別:

SIZE和CSize:{cx; cy;} // 不是寬和高

?

<!--[if !supportLists]-->l???? <!--[endif]-->浮點數大小類SizeF:

class SizeF {

public:

??? SizeF() {Width = Height = 0.0f;}

??? SizeF(const SizeF& size) {Width = size.Width; Height = size.Height;}

??? SizeF(REAL width, REAL height) {Width = width; Height = height;}

??? SizeF operator+(const SizeF& sz) const {

??????? return SizeF(Width + sz.Width, Height + sz.Height);

?????? }

??? SizeF operator-(const SizeF& sz) const {

??????? return SizeF(Width - sz.Width, Height - sz.Height);

??? }

??? BOOL Equals(const SizeF& sz) const {

??????? return (Width == sz.Width) && (Height == sz.Height);

??? }

??? BOOL Empty() const {return (Width == 0.0f && Height == 0.0f);}

public:

??? REAL Width;

??? REAL Height;

};

(3)Rect[F](矩形)
GDI+中,也有兩種類型的矩形:整數矩形(對應于Rect類)和浮點數矩形(對應于RectF類)。下面分別加以介紹:

<!--[if !supportLists]-->l???? <!--[endif]-->整數矩形類Rect:

class Rect {

public:

??? Rect() {X = Y = Width = Height = 0;}

??? Rect(INT x, INT y, INT width, INT height);

??? Rect(const Point& location, const Size& size);

??? Rect* Clone() const;

??? VOID GetLocation(OUT Point* point) const;

??? VOID GetSize(OUT Size* size) const;

??? VOID GetBounds(OUT Rect* rect) const;

??? INT GetLeft() const {return X;}

??? INT GetTop() const {return Y;}

??? INT GetRight() const {return X+Width;}

??? INT GetBottom() const {return Y+Height;}

??? BOOL IsEmptyArea() const{return (Width <= 0) || (Height <= 0);}

??? BOOL Equals(const Rect & rect) const;

??? BOOL Contains(INT x, INT y) const;

??? BOOL Contains(const Point& pt) const;

??? BOOL Contains(Rect& rect) const;

??? VOID Inflate(INT dx, INT dy) {

??????? X -= dx;??????????????? Y -= dy;

??????? Width += 2*dx;????? Height += 2*dy;

??? }

??? VOID Inflate(const Point& point) {Inflate(point.X, point.Y);}

??? BOOL Intersect(const Rect& rect) {return Intersect(*this, *this, rect);}

??? static BOOL Intersect(OUT Rect& c, const Rect& a, const Rect& b);

??? BOOL IntersectsWith(const Rect& rect) const;

??? static BOOL Union(OUT Rect& c, const Rect& a, const Rect& b);

??? VOID Offset(const Point& point);

??? VOID Offset(INT dx, INT dy);

public:

??? INT X; // 不是left和top

??? INT Y;

??? INT Width; // 更不是right和bottom

??? INT Height;

};

注意,這里的矩形與GDI的區別:

RECT:{left; top; right; bottom;}; // 不是寬和高

雖然Rect中的(X, Y)等價于RECT的( left, top),但是Rect中的(Width, Height)卻不同于RECT的( right, bottom)。

?

<!--[if !supportLists]-->l???? <!--[endif]-->浮點數矩形類RectF:

class RectF {

public:

??? RectF() {X = Y = Width = Height = 0.0f;}

??? RectF(REAL x, REAL y, REAL width, REAL height);

??? RectF(const PointF& location, const SizeF& size);

??? RectF* Clone() const;

??? VOID GetLocation(OUT PointF* point) const;

??? VOID GetSize(OUT SizeF* size) const;

??? VOID GetBounds(OUT RectF* rect) const;

??? REAL GetLeft() const;

??? REAL GetTop() const;

??? REAL GetRight() const;

??? REAL GetBottom() const;

??? BOOL IsEmptyArea() const;

??? BOOL Equals(const RectF & rect) const;

??? BOOL Contains(REAL x, REAL y) const;

??? BOOL Contains(const PointF& pt) const;

??? BOOL Contains(const RectF& rect) const;

??? VOID Inflate(REAL dx, REAL dy);

??? VOID Inflate(const PointF& point);

??? BOOL Intersect(const RectF& rect);

??? static BOOL Intersect(OUT RectF& c, const RectF& a, const RectF& b);

??? BOOL IntersectsWith(const RectF& rect) const;

??? static BOOL Union(OUT RectF& c, const RectF& a, const RectF& b);

??? VOID Offset(const PointF& point);

??? VOID Offset(REAL dx, REAL dy);

public:

??? REAL X;

??? REAL Y;

??? REAL Width;

??? REAL Height;

};

?

在GDI的MFC封裝中,也有點、大小和矩形的

<!--[if !supportLists]-->n???????? <!--[endif]-->結構:(windef.h)

typedef struct tagPOINT {LONG x; LONG y;} POINT; // typedef long LONG;

typedef struct tagSIZE {LONG cx; LONG cy;} SIZE;

typedef struct tagRECT {LONG left; LONG top; LONG right; LONG bottom;} RECT;

?

<!--[if !supportLists]-->n???????? <!--[endif]-->類:(atltypes.h)

class CPoint : public tagPOINT {

public:

?????? CPoint() throw();

?????? CPoint(int initX, int initY) throw();

?????? ……

}

class CSize : public tagSIZE {

public:

?????? CSize() throw();

?????? CSize(int initCX, int initCY) throw();

?????? ……

}

class CRect : public tagRECT {

public:

?????? CRect() throw();

?????? CRect(int l, int t, int r, int b) throw();

?????? ……

}

可見,這幾個類都是從對應的結構派生的。GDI中,之所以有了類還要保留結構,主要是考慮效率和與底層GDI API的兼容。

比較可知,GDI和GDI+都有對應的類,不過GDI+沒有對應的結構(但有浮點數版類),而GDI則沒有對應的浮點數版類(但卻有結構)。

總結

以上是生活随笔為你收集整理的MFC使用GDI+编程设置的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。