Wxt's Blog

专注于 GUI 程序设计
随笔 - 4, 文章 - 0, 评论 - 1, 引用 - 0
数据加载中……

2015年7月29日

为什么std::wstring不提供CString那样的Format的方法

很多时候想使用字符串格式化输出,但是std::wstring偏偏没有提供这个方法。CString只存在于ATL/MFC,使用Win32平台没有CString可用,使用底层的spintf之类的函数,又时常担心buffer越界,写重复的越界检测之类的代码...所以这里把CString的Format方法搬了过来:
String.h
1 class String : public std::wstring
2 {
3 public:
4     void Format(const wchar_t* pszFormat, );
5 protected:
6     void FormatV(const wchar_t* pszFormat, va_list args);
7     int GetFormattedLength(const wchar_t* pszFormat, va_list args);
8     int Format(wchar_t* pszBuffer, ULONG nLength, const wchar_t* pszFormat, va_list args);
9 };
String.cpp
std::wstring StrFormat( const wchar_t* pstrFormat,  )
{
    WCHAR szBuffer[300] = { 0 };
    va_list args;
    va_start(args, pstrFormat);
    ::wvnsprintf(szBuffer, lengthof(szBuffer) - 2, pstrFormat, args);
    wcscat_s(szBuffer, 300, L"\n");
    va_end(args);
    return szBuffer;
}

void String::Format( const wchar_t* pszFormat,  )
{
    va_list arglist;
    va_start(arglist, pszFormat);
    FormatV(pszFormat, arglist);
    va_end(arglist);
}

int String::Format( wchar_t* pszBuffer, ULONG nLength, const wchar_t* pszFormat, va_list args )
{
    return vswprintf_s(pszBuffer, nLength, pszFormat, args);
}

void String::FormatV( const wchar_t* pszFormat, va_list args )
{
    if (pszFormat == NULL)
    {
        return;
    }
    ULONG nLength = GetFormattedLength(pszFormat, args);
    wchar_t* pszBuffer = new wchar_t[nLength + 1];
    ::ZeroMemory(pszBuffer, nLength + 1);
    Format(pszBuffer, nLength + 1, pszFormat, args);
    std::wstring::operator=(std::wstring(pszBuffer));
    delete []pszBuffer;
}

int String::GetFormattedLength( const wchar_t* pszFormat, va_list args )
{
    return _vscwprintf(pszFormat, args);
}

以上代码在VS2008编译通过。

posted @ 2015-07-29 18:23 wxt 阅读(678) | 评论 (0)编辑 收藏

2015年4月27日

查看某个文件正在被哪些进程访问

通过使用Sysinternals的procexp.exe工具提供的Process Explorer Search(菜单->Find->Find Handle or Dll或Ctrl+F)功能,我们可以看到某个文件正在被哪些进程使用。这个功能在你想删除某个文件,而系统提示“该文件正在被占用,不能删除”的时候非常有用。

posted @ 2015-04-27 23:28 wxt 阅读(364) | 评论 (0)编辑 收藏

2015年3月19日

Gdiplus的初始化辅助类

在使用Gdiplus的功能之前,要先进行初始化,对应的函数是Gdiplus::GdiplusStartup,在使用完Gdiplus的功能之后,要进行反初始化,对应的函数则是Gdiplus::GdiplusShutdown。
为了简化编程,这里实现了一个简单的Gdiplus初始化类,作为全局对象使用,类似于MFC的theApp对象。代码如下:
#pragma once

#include <GdiPlus.h>

class GdiPlusHelper
{
public:
    GdiPlusHelper()
    {
        Gdiplus::GdiplusStartupInput gdiplusStartupInput;
        Gdiplus::GdiplusStartup(&m_nGdiPlusToken, &gdiplusStartupInput, NULL);
    }
    ~GdiPlusHelper()
    {
        Gdiplus::GdiplusShutdown(m_nGdiPlusToken);
    }
    ULONG_PTR m_nGdiPlusToken;
};

posted @ 2015-03-19 15:14 wxt 阅读(426) | 评论 (0)编辑 收藏

2015年3月18日

利用GdiPlus::Matrix实现图形旋转

用Gdiplus::Matrix对图形进行简单的旋转,可以免除繁琐的数学计算。
这里主要用到了Gdiplus::Matrix::RotateAt和Gdiplus::Graphics::SetTransForm实现图形旋转。

1、类GdiPlus::Matrix的RotateAt方法,原型如下:
Status RotateAt( REAL angle,
    const PointF &center,
    MatrixOrder order
);
参数angle为需要旋转的角度,center为旋转的中心,order为旋转Matrix的顺序。order的取值有两个:Gdiplus::MatrixOrderPrepend和Gdiplus::MatrixOrderAppend,默认取值为Gdiplus::MatrixOrderPrepend。

2、类Gdiplus::Graphics的SetTransForm方法,原型如下:
Status SetTransform( const Matrix *matrix
);
参数matrix就是上面的Gdiplus::Matrix对象指针。

示例代码如下:
VOID Example_Rotate(HDC hdc)
{
   Gdiplus::Graphics graphics(hdc);
   Gdiplus::Pen pen(Color(255, 0, 0, 255));
   Gdiplus::Matrix matrix;
   Gdiplus::PonitF P(50, 50);             // 旋转中心
   matrix.RotateAt(100.0f, P);               // 旋转100度
   graphics.SetTransform(&matrix);
   graphics.DrawEllipse(&pen, 0, 0, 100, 50); 
}

效果展示:


参考资料:MSDN

posted @ 2015-03-18 15:34 wxt 阅读(2234) | 评论 (1)编辑 收藏