最新消息

[公告2014/05/30] 如有需要將部落格中,任何一篇文章的程式碼使用在商業用途,請與我聯繫。

[公告2015/04/26] Line版的 iInfo程式與投資應用 群組已上線想加入的朋友們,請先查看 "入群須知" 再與我聯繫 Line : aminwhite5168,加入請告知身分與回答 "入群須知" 的問題。

[公告2018/04/22] 台北 Python + Excel VBA 金融資訊爬蟲課程,課程如網頁內容 金融資訊爬蟲班:台北班 Python 金融資訊爬蟲、EXCEL VBA 金融資訊爬蟲

[公告2019/01/08] 請注意:我再次重申,部落格文章的程式碼,是要提供各位參考與學習,一旦網頁改版請自行修改,別要求東要求西要我主動修改,你們用我寫東西賺錢了、交差了,請問有分我一杯羹嗎?既然賺錢沒分我,請問有什麼理由要求我修改,如果沒能力改,就花錢來找我上課。

[公告2019/12/01] 若各位有 Excel VBA 案子開發需求,歡迎與我聯繫,可接案處理。

[公告2020/05/22] 頁面載入速度慢,起因為部分JS來源(alexgorbatchev.com)失效導致頁面載入變慢,目前已做調整,請多見諒。

2019年10月10日 星期四

GDI+ (2):VC++ 2010 使用 GDI+ 將文字轉 -45度角

繼前一篇 GDI+ (1):VC++ 2010 使用 GDI+ 將文字旋轉圍繞  後,再度使用 GDI+ 搭配三角函數,將文字旋轉一個角度,並做到通用的角度計算,以方便後續使用。
由 VS2010中 已經有GDI+ ,所以就不用額外再安裝SDK,即可直接使用,若VC6就要另外安裝Windows SDK。

Step 1. 建立一個名為 CRotateTransformText 的 C++ Dialog專案,在 stdafx.h 加入以下GDI+ 的宣告。
#include "gdiplus.h"
#pragma comment(lib,"gdiplus.lib")
using namespace Gdiplus;

Step 2. 在 CRotateTransformTextDlg.h 加入物件宣告
GdiplusStartupInput m_gdiplusStartupInput;
ULONG_PTR m_pGdiToken;

Step 3. 在CRotateTransformTextDlg.cpp 的 OnInitDialog 函數中,添加以下程式碼,初始化 GDI+ 物件。
GdiplusStartup(&m_pGdiToken, &m_gdiplusStartupInput, NULL);

Step 4. 在CRotateTransformTextDlg.cpp 的  OnPaint 函數中,添加以下程式碼。
void CRotateTransformTextDlg::OnPaint()
{
 CPaintDC dc(this);
 CMemDC  mdc(dc, this); //從VS2008含SP1之後才有支援,以雙緩衝防止畫面閃爍
 Graphics grpx(mdc.GetDC());
 Color  *rgb = new Color(255, 255, 255);
 Pen   pen(Color(0,0,255), 2); //設定畫筆顏色與粗細
 RectF  rf;
 CStringW str;
 CRect  rect;
 REAL  X, Y;

 //取得Dialog高寬
 GetClientRect(&rect);

 //設定Dialog顏色
 grpx.Clear(*rgb);

 //指定消除鋸齒的呈現
 grpx.SetSmoothingMode(SmoothingModeAntiAlias);

 //設定字型格式
 FontFamily  fontFamily(L"微軟正黑體");
 int px = 16;
 int style = FontStyleRegular;
 Gdiplus::Font font(&fontFamily, (REAL)px, style, UnitPixel);

 //設定繪圖的位置 
 *rgb = Color(255, 0, 255); 

 //旋轉-45度
 int degree = -45;

 //取出間隔
 float h, gap = rect.Width() / 9;

 for(int i = 0 ; i < 8 ; i++)
 {
  //設定字型內容
  str.Format(L"%04d", i);

  //取得字串寬高
  grpx.MeasureString(str, str.GetLength(), &font, PointF(0, 0), &rf );
  
  //計算經過旋轉後,字串左上角的點到X軸的距離
  //依據畢氏定理a^2 + b^2 = c^2
  //h = a = (c^2 * (1 - cosθ^2))^0.5
  h = sqrt(pow(rf.Width, 2)*(1-pow(cos(degree * M_PI / 180), 2)));

  //計算字串間距離與長度
  X = rect.left + h + gap * i;  
  Y = rect.Height() / 2;  

  //將X, Y平移至繪圖點上,並將X, Y 定為0, 0
  grpx.TranslateTransform(X, Y);

  //設定文字旋轉角度
  grpx.RotateTransform(degree);

  //畫矩形框
  grpx.DrawRectangle(&pen, 0, 0, (int)rf.Width, (int)rf.Height);

  //設定文字為位置
  rf.X = rf.Y = 0;
  grpx.DrawString(str, str.GetLength(), &font, rf, 0, &SolidBrush(*rgb));

  //還原座標
  grpx.ResetTransform();
 }
}
20行:設定繪圖的品質。
SmoothingModeInvalid =-1; {指定一個無效模式}
SmoothingModeDefault   =0;  {指定不消除鋸齒}
SmoothingModeHighSpeed  =1;  {指定高速度、低品質呈現}
SmoothingModeHighQuality =2;  {指定高品質、低速度呈現}
SmoothingModeNone =3;  {指定不消除鋸齒}
SmoothingModeAntiAlias  =4;  {指定消除鋸齒的呈現}
參考資料:SmoothingMode Enumeration

23、26行:Font 為gdiplus中的Class。
參考資料:gdiplusheaders.h header

48行:依據畢氏定理與三角函數,計算高度,並寫成通用的計算方法,可計算各角度的高。
$$\Large a^{2} + b^{2} = c^{2} \\\\ $$ \begin{eqnarray*} && \Large \Rightarrow a^{2} + \left (c^{2}\cdot \cos^{2}\Theta\right ) = c^{2}\\\\ && \Large \Rightarrow a^{2} = c^{2}\left (1 - \cos^{2}\Theta \right ) \\\\ && \Large \Rightarrow a = \sqrt{c^{2}\left (1 - \cos^{2}\Theta \right )}\ \end{eqnarray*}
Step 5. 在CRotateTransformTextDlg.cpp 的  OnDestroy() 函數中,添加以下程式碼。
GdiplusShutdown(m_pGdiToken);
專案下載

執行畫面


沒有留言:

張貼留言