2007年1月17日星期三

Copy custom data to clipboard

Follow the below steps can copy a new clipboard format data to clipboard

  1. Use RegisterClipboardFormat function to register a new clipboard format
  2. Use GlobalAlloc function to allocate the specified number of bytes from the heap
  3. Use GlobalLock function to get a pointer to the first byte of the object's memory block, and then use memcpy to copy data to this pointer
  4. Use GlobalUnlock to decrement the lock count associated with a memory object
  5. Use OpenClipboard to open the clipboard
  6. Use EmptyClipboard to empty the clipboard as need
  7. Use SetClipboardData to copy data to the clipboard
  8. Use CloseClipboard to close the clipboard
Below is an example

// Custom data
unsigned char cData[] = {0x01, 0x02, 0x32, 0x45};
int dLen = sizeof(cData)/sizeof(unsigned char);

// Register a new clipboard format named "cf/new-cf-name"
UINT cfType = RegisterClipboardFormat("cf/new-cf-name");
if (!cfType) {
    AfxMessageBox("Register clipboard format error");
    return;
}

// Alloc
HGLOBAL hGlobalData = GlobalAlloc(GMEM_DDESHARE, dLen);
if (!hGlobalData)
{
    return;
}

// Lock the handle and copy the custom data to the buffer.
char* sData = (char*)GlobalLock(hGlobalData);
memcpy(sData, cData, dLen);
GlobalUnlock(hGlobalData);

// Open Clipboard
if (OpenClipboard())
{
    // Remove the current Clipboard contents
    if (EmptyClipboard())
    {
        if (!::SetClipboardData(cfType, hGlobalData)) {
            AfxMessageBox("Unable to set Clipboard data");
        }
    }
    CloseClipboard();
}

Copy Enhance Metafile to Clipboard


// Below is an example to copy a enhance metafile to clipboard by using win32 API
RECT rc;

// Calculate the metafile width and height
// Convert from pixel dimensions to MM dimensions since
// metafile use MM dimensions(in .01-millimeter units)
HDC hDC = ::GetDC(hWnd);
int iWidthMM = GetDeviceCaps(hDC, HORZSIZE);
int iHeightMM = GetDeviceCaps(hDC, VERTSIZE);
int iWidthPels = GetDeviceCaps(hDC, HORZRES);
int iHeightPels = GetDeviceCaps(hDC, VERTRES);
::ReleaseDC(hWnd, hDC);
int iMMPerPelX = (iWidthMM * 100)/iWidthPels;
int iMMPerPelY = (iHeightMM * 100)/iHeightPels;

rc.left = 0 * iMMPerPelX;
rc.top = 0 * iMMPerPelY;
rc.right = 100 * iMMPerPelX;
rc.bottom = 100 * iMMPerPelY;

// Create the metafile and draw a rectangle
HDC hMetaDC = CreateEnhMetaFile((HDC)NULL, NULL, &rc, "ddd");
Rectangle(hMetaDC, 0, 0, 100, 100);
HENHMETAFILE hMetaFile = CloseEnhMetaFile(hMetaDC);

// Open Clipboard
if (OpenClipboard())
{
    // Remove the current Clipboard contents
    if (EmptyClipboard())
    {
        if (!::SetClipboardData(CF_ENHMETAFILE, hMetaFile))
        {
            AfxMessageBox("Unable to set Clipboard data");
        }
    } else {
        AfxMessageBox("Copy Data to clipboard Error: Cannot empty the Clipboard");
    }
    CloseClipboard();
} else {
    AfxMessageBox("Copy Data to clipboard Error: Cannot open the Clipboard");
}
DeleteEnhMetaFile(hMetaFile);

2006年12月30日星期六

给对话框中的CTreeCtrl控件添加右键菜单

给对话框中的CTreeCtrl控件添加右键菜单,有几种方法,一种是从CTreeCtrl派生一个类,在这个类的WM_RBUTTONDOWN中弹出右键菜单,但这样做会增加类。另一个方法就是在对话框的WM_CONTEXTMENU消息中,弹出右键菜单:

void TreeTestDlg::OnContextMenu(CWnd* pWnd, CPoint point)
{
    if (pWnd == &m_treeCtrl) {
        UINT flags;
        m_treeCtrl.ScreenToClient(&point);
        HTREEITEM hItem = m_treeCtrl.HitTest(point, &flags);
        if (hItem) {
            m_treeCtrl.SelectItem(hItem);
            showTreePopMenu(point, hItem);
        }
    }
}

其中,showTreePopMenu,用来弹出右键菜单:
void TreeTestDlg::showTreePopMenu(CPoint& point, HTREEITEM hItem)
{
    CMenu menu;
    CMenu* pMenu = NULL;
    menu.LoadMenu(IDR_TREE_MENU);
    pMenu = menu.GetSubMenu(0); // 0表示取第一个子菜单
    if (!pMenu) return;
    GetCursorPos(&point);
    pMenu->TrackPopupMenu(TPM_LEFTALIGN, point.x, point.y, this);
}

如何让搜索引擎收录我的站点

方法一:主动向搜索引擎提交自己的网址
向百度、Google、Yahoo提交网址是不用花钱的,其提交页面分别为:
http://www.baidu.com/search/url_submit.html
http://www.google.com/intl/zh-CN/add_url.html
http://www.yisou.com/search_submit.html?source=yisou_www_hp

方法二:和同类且已被收录的网站做链接
这 个很简单了,如果你的网站刚刚建成,而朋友的网站已经被几个搜索引擎收录了,那么就和他交换一下 首页链接,这样,下次搜索引擎抓取他网站上的内容的时候就会“顺便”发现你的网站(起到跳板的作用),并予以收录。需要注意的是,这种友情链接应以文本链 接和logo的形式存在,而不要采用图片热点或flash的形式。另外就是回避那种通过CGI程序管理友情链接的网站,这种网站通常把链接存在数据库中, 随意排序、变换位置,导致搜索引擎无法正常的找到你的网址。

方法三:合理、合法的对网站进行SEO(搜索引擎优化)
关于网站优化方面的文章网上很多,不过很可惜,良莠不齐,新旧不分,同时因为SEO是一项经验、技术并重的业务,所以别人也很难或不愿意把自己掌握的东西告诉你,因此,只能靠自己分辨识别了。关于这部分,请查看页面地址 http://www.dfm369.com/20050925/20050512001.html

纯资源DLL的编写

纯资源的DLL就是只包含资源的DLL,例如:图标,位图,字符串,声音,视频,对话框等。使用纯资源DLL可以节约可执行文件的大小,可以被所有的应用程序所共享,从而提高系统性能。纯资源DLL的编写比普通的DLL要简单的多:
1) 创建一个WIN32 DLL工程,不是MFC的DLL
2) 创建一个资源文件 *.RC,添加到资源DLL的工程中去
3) 添加一个初始化DLL的原文件:

#include "windows.h"
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
{
return 1;
}

这是纯资源DLL所必须需的代码,保存这个文件为*.CPP。编译这个资源DLL。

在应用程序显示的调用这个DLL,使用LoadLibrary函数装入资源DLL,FindResource和LoadResource来装入各种资源,或者使用下列的特定的资源装入函数:
FormatMessage
LoadAccelerators
LoadBitmap
LoadCursor
LoadIcon
LoadMenu
LoadString
当资源使用结束,应用程序须调用FreeLibrary函数来释放资源。

调用编写好的资源DLL的步骤如下:
首先在应用程序中声明一个DLL的句柄,HINSTANCE m_hLibrary;在OnCreate( )
函数中调用LoadLirbrary( ),在OnDestory( )中调用FreeLibrary()。

2006年12月28日星期四

使用c/c++判断文件是否存在

// Test whether a file is exist or not
bool fileExists(const char* fileName)
{
    if (!fileName) return false;


#ifdef WIN32
    struct _stat buf;
    int result;

    result = _stat(fileName, &buf);

    if (result) {
        return false;
    }

    return (buf.st_mode & _S_IFMT) == _S_IFREG;
#else
    struct stat buf;
    int result;

    result = stat(fileName, &buf);

    if (result) {
        return false;
    }

    return (buf.st_mode & S_IFMT) == S_IFREG;
#endif
}

Win32 API SHFileOperation

The win32 API SHFileOperation can be used to delete a whole directory or copy a directory from a path to another, below is an example:

// Delete the whole directory
BOOL DelDir(LPCTSTR lpszPath)
{
    char fPath[MAX_PATH];
    memset(fPath, 0, sizeof(fPath));

    strcpy(fPath, lpszPath);

    // Note : 目录不能以\或/结尾
    for (int i = strlen(fPath) - 1; i >= 0; i--) {
        if (fPath[i] == '\\' || fPath[i] == '/') {
            fPath[i] = 0;
        } else {
            break;
        }
    }

    SHFILEOPSTRUCT FileOp;
    FileOp.fFlags = FOF_NOCONFIRMATION;
    FileOp.hNameMappings = NULL;
    FileOp.hwnd = NULL;
    FileOp.lpszProgressTitle = NULL;
    FileOp.pFrom = fPath;
    FileOp.pTo = NULL;
    FileOp.wFunc = FO_DELETE;
    return SHFileOperation(&FileOp) == 0;
}

// Copy Directory or file, 注意字符串fromPath与toPath必须以"\0\0"结尾,
// 且目录的文件分割符是'\',不是'/'
BOOL copy(LPCTSTR fromPath, LPCTSTR toPath)
{
    SHFILEOPSTRUCT FileOp;
    FileOp.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR;
    FileOp.hNameMappings = NULL;
    FileOp.hwnd = NULL;
    FileOp.lpszProgressTitle = NULL;
    FileOp.pFrom = fromPath;
    FileOp.pTo = toPath;
    FileOp.wFunc = FO_COPY;
    return SHFileOperation(&FileOp) == 0;
}