2008-08-05 07:30 windows sdk编程系列文章 ---- 文件压缩

来源:互联网 发布:网络变压器 好坏 编辑:程序博客网 时间:2024/04/27 16:55

http://hi.baidu.com/combojiang/item/d767050c8679457bbfe97e36

理论:

aPLib(http://www.ibsensoftware.com)由卓越的编程大师Joergen Ibsen创建,是一个商业压缩库,供压缩程序数据的编程人员使用。aPLib是压缩领域中性能最优的产品之一,许多压缩程序用它压缩可执行文件。

有一些作免杀的朋友也常常会用到这个压缩引擎,它可以用在你的压缩壳里。它既可以对整个文件进行压缩,也可以对文件的一部分进行压缩。本篇采用的aPlib版本是0.36。

本篇用到的函数:
1。压缩函数:
extern "C" size_t aP_pack( const void *source,
                void *destination,
                size_t length,
                void *workmem,
                BOOL (*callback)(size_t, size_t));

//下面这个函数用于获取压缩引擎需要的临时缓冲的大小。
extern "C" size_t aP_workmem_size( size_t input_size );

2。解压缩函数:
extern "C" size_t aP_depack_asm_fast( const void *source,
                           void *destination );

本篇采用的是静态库aPlib.lib, 这样更具有隐蔽性。另外,我们在代码中使用的压缩和解压缩的判断标志,你可以根据自己的情况做出调整。理论比较简单,我们直接看代码。

代码:见光盘vcappack
#include "windows.h"
#include "commctrl.h"
#include "Commdlg.h"
#include "shellapi.h"
#include "oleauto.h"
#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"shell32.lib")
#pragma comment(lib,"Comdlg32.lib")
#pragma comment(lib,"aplib.lib")
#pragma comment(lib,"oleaut32.lib")

extern "C" size_t aP_pack( const void *source,
                void *destination,
                size_t length,
                void *workmem,
                BOOL (*callback)(size_t, size_t));
extern "C" size_t aP_workmem_size( size_t input_size );
extern "C" size_t aP_depack_asm_fast( const void *source,
                           void *destination );

/**************************************************************/
char szClassName[] = "aPLib_Class";
char szDisplayName[] = "aPLib Pack";
char plSelect[] = "Please Select File First";
char btnClass[] = "BUTTON";
char EditClass[] = "EDIT";
char statClass[] = "STATIC";
CHAR tbClass[] = "ToolbarWindow32";
CHAR aborted[] = "Packing aborted";

BOOL   Packing;   
BOOL   ContPack = 1;
BOOL   killFlag;  
  
HICON g_hIcon;
HWND g_hWnd;
HWND g_hToolBar;
HBITMAP g_hTbBmp;
DWORD g_ThreadID;
HINSTANCE g_hInstance;

HWND   g_hEdit1;
HWND   g_hButn1;
HWND   g_hButn2;
HWND   g_hStat1;

char szFileName[MAX_PATH];
char szFilter[] = "*.* \0";
char SaveFile1[] = "Save File As";
char Patn1[] = "*.*\0";
OPENFILENAME     g_ofn;



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

HBITMAP SetBmpColor (HBITMAP hBitmap)
{
    HDC mDC;
    HBRUSH hBrush;
    HBITMAP hOldBmp;
    HBITMAP hReturn;
    HBRUSH hOldBrush;

    mDC = CreateCompatibleDC(NULL);
    hOldBmp = (HBITMAP) SelectObject(mDC,hBitmap);

    hBrush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
    hOldBrush = (HBRUSH)SelectObject(mDC,hBrush);

    ExtFloodFill(mDC,1,1,GetPixel(mDC,1,1),FLOODFILLSURFACE);
    SelectObject(mDC,hOldBrush);
    DeleteObject(hBrush);

    hReturn = (HBITMAP)SelectObject(mDC,hBitmap);
    DeleteDC(mDC);
    return hReturn;
}

void Do_ToolBar(HWND hWnd)
{
    TBBUTTON tbb;
    TBADDBITMAP tbab;
    DWORD dwSize;
   
    g_hTbBmp = LoadBitmap(g_hInstance,MAKEINTRESOURCE(750));

    g_hToolBar = CreateWindowEx(0,tbClass,szDisplayName,WS_CHILD |WS_VISIBLE|CCS_NODIVIDER | TBSTYLE_FLAT,
        0,0,500,40,hWnd,NULL,g_hInstance,NULL);

    SendMessage(g_hToolBar,TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON),0);
    dwSize = 4915275;
    SendMessage(g_hToolBar,TB_SETBITMAPSIZE,0,dwSize);
    g_hTbBmp = SetBmpColor(g_hTbBmp);
    tbab.hInst = 0;
    tbab.nID = (DWORD)g_hTbBmp;
   
    SendMessage(g_hToolBar,TB_ADDBITMAP,12,(LPARAM)&tbab);
    SendMessage(g_hToolBar,TB_SETBUTTONSIZE,0,dwSize);

    tbb.fsState = TBSTATE_ENABLED;
    tbb.dwData = 0;
    tbb.iString = 0;

    tbb.iBitmap = 0;
    tbb.idCommand = 50;
    tbb.fsStyle = TBSTYLE_BUTTON;
    SendMessage(g_hToolBar,TB_ADDBUTTONS,1,(LPARAM)&tbb);

    tbb.iBitmap = 1;
    tbb.idCommand = 51;
    tbb.fsStyle = TBSTYLE_BUTTON;
    SendMessage(g_hToolBar,TB_ADDBUTTONS,1,(LPARAM)&tbb);

    tbb.iBitmap = 2;
    tbb.idCommand = 52;
    tbb.fsStyle = TBSTYLE_BUTTON;
    SendMessage(g_hToolBar,TB_ADDBUTTONS,1,(LPARAM)&tbb);

    tbb.iBitmap = 3;
    tbb.idCommand = 53;
    tbb.fsStyle = TBSTYLE_BUTTON;
    SendMessage(g_hToolBar,TB_ADDBUTTONS,1,(LPARAM)&tbb);

   
}

HWND EditSl(CHAR *szDisplayName,DWORD x, DWORD y, DWORD wd,DWORD ht,HWND hParent,DWORD Editid)
{
    return CreateWindowEx(WS_EX_CLIENTEDGE,EditClass,szDisplayName,
                WS_VISIBLE | WS_CHILDWINDOW | ES_AUTOHSCROLL |ES_NOHIDESEL,
              x,y,wd,ht,hParent,(HMENU)Editid,g_hInstance,NULL);
}

HWND PushButton(CHAR *szDisplayName,DWORD x, DWORD y, DWORD wd,DWORD ht,HWND hParent,DWORD Btnid)
{
     return CreateWindowEx(0, btnClass,szDisplayName,
            WS_CHILD | WS_VISIBLE,
            x,y,wd,ht,hParent,(HMENU)Btnid,
            g_hInstance,NULL);
}

HWND Static(CHAR *szDisplayName,DWORD x, DWORD y, DWORD wd,DWORD ht,HWND hParent,DWORD stcid)
{
    return CreateWindowEx(WS_EX_STATICEDGE,
            statClass,szDisplayName,
            WS_CHILD | WS_VISIBLE | SS_CENTER,
            x,y,wd,ht,hParent,(HMENU)stcid,
            g_hInstance,NULL);
}

void SaveFileName(HWND hParent,char *lpTitle,char *lpfilter)
{
    g_ofn.lStructSize = sizeof(OPENFILENAME);
    g_ofn.hwndOwner = hParent;
    g_ofn.hInstance = g_hInstance;
    g_ofn.lpstrFilter = lpfilter;
    g_ofn.lpstrFile = szFileName;
    g_ofn.nMaxFile = MAX_PATH;
    g_ofn.lpstrTitle = lpTitle;
    g_ofn.Flags = OFN_EXPLORER|OFN_LONGNAMES|OFN_OVERWRITEPROMPT;
    GetSaveFileName(&g_ofn);
}

BOOL cbProc(size_t len1,size_t len2)
{
    CHAR buff[32];
    char buf2[16];
    wsprintf(buff,"%d",len1);
    wsprintf(buf2,"%d",len2);

    lstrcat(buff,"=>");
    lstrcat(buff,buf2);

    SendMessage(g_hStat1,WM_SETTEXT,0,(LPARAM)buff);

    return ContPack;
}

DWORD WINAPI PackFile(
LPVOID lpParameter
)
{
    HANDLE hFile;
    DWORD ln;
    BSTR source;
    BSTR dest;
    BSTR working;
    DWORD br;
    size_t clenth;
    char szNameFile[128] = {0};

    GetWindowText(g_hEdit1,szNameFile,128);
    if(szNameFile[0] =='\0')
    {
        MessageBox(g_hWnd,plSelect,szDisplayName,MB_OK);
        return 0;
    }

    hFile = CreateFile(szNameFile,GENERIC_READ,FILE_SHARE_READ,NULL,
        OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

    ln = GetFileSize(hFile,NULL);
    source = SysAllocStringByteLen(0,ln);
   
    ReadFile(hFile,source,ln,&br,NULL);
    CloseHandle(hFile);

    DWORD * pStr = (DWORD *)source;
    if(*pStr == 0x32335041) //"23PA"
    {
        MessageBox(g_hWnd,"This file has already been compressed!",szDisplayName,MB_OK);
        SysFreeString(source);
        return 0;
    }
   
    dest = SysAllocStringByteLen(0,ln+8);
    working = SysAllocStringByteLen(0,aP_workmem_size(ln));

    Packing = 1;
    ContPack = 1;
   
    clenth = aP_pack(source,dest+4,ln,working,cbProc);
    if(clenth == 0)
    {
        SendMessage(g_hStat1,WM_SETTEXT,0,(LPARAM)aborted);
        goto Abort;
    }

     pStr = (DWORD*)dest;
    *pStr = 0x32335041;
    pStr++;
    *pStr = ln;

    szFileName[0] = '\0';
    SaveFileName(g_hWnd,SaveFile1,Patn1);
    if(szFileName[0] != '\0')
    {
        hFile = CreateFile(szFileName,GENERIC_WRITE,
            NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,
            NULL);

        clenth += 8;
        WriteFile(hFile,dest,clenth,&br,NULL);
        CloseHandle(hFile);
    }

Abort:
    SysFreeString(source);
    SysFreeString(dest);
    SysFreeString(working);
    Packing = 0;
    return 0;
}

void UnPackFile()
{
    HANDLE hFile;
    DWORD ln;
    BSTR source;
    BSTR dest;
    DWORD br;
    size_t dsize;
    char szNameFile[128] = {0};

    GetWindowText(g_hEdit1,szNameFile,128);
    if(szNameFile[0] == '\0')
    {
        MessageBox(g_hWnd,plSelect,szDisplayName,MB_OK);
        return ;
    }

    hFile = CreateFile(szNameFile,GENERIC_READ,FILE_SHARE_READ,NULL,
        OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

    ln = GetFileSize(hFile,NULL);
    source = SysAllocStringByteLen(0,ln);
    ReadFile(hFile,source,ln,&br,NULL);
    CloseHandle(hFile);

    DWORD * pStr = (DWORD *)source;
    if(*pStr == 0x32335041) //"23PA"
    {
        MessageBox(g_hWnd,"This file has not been compressed!",szDisplayName,MB_OK);
        SysFreeString(source);
        return;
    }
    pStr++;
    dsize = *pStr;
    dest = SysAllocStringByteLen(0,dsize);

    aP_depack_asm_fast(source + 4,dest);

    szFileName[0] = '\0';
    SaveFileName(g_hWnd,SaveFile1,Patn1);
   
    if(szFileName[0] != '\0')
    {
        hFile = CreateFile(szFileName,GENERIC_WRITE,NULL,NULL,
            CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

        WriteFile(hFile,dest,dsize,&br,NULL);
        CloseHandle(hFile);
    }
   
    SysFreeString(source);
    SysFreeString(dest);

}

LRESULT CALLBACK WindowProc(          HWND hwnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
)
{
    HFONT hFont;
    switch(uMsg)
    {
    case WM_COMMAND:
        {
            if(Packing == 0)
            {
                if(wParam == 50)
                {
                   
                    HANDLE hThread = CreateThread(NULL,NULL,PackFile,NULL,0,&g_ThreadID);
                    CloseHandle(hThread);
                }
                else if(wParam == 51)
                {
                    UnPackFile();
                }

                else if(wParam == 53)
                {
                    SendMessage(hwnd,WM_SYSCOMMAND,SC_CLOSE,NULL);
                }
                else if (wParam == 54)
                {
                    szFileName[0] = 0;
                   
                    g_ofn.lStructSize = sizeof(OPENFILENAME);
                    g_ofn.hwndOwner = hwnd;
                    g_ofn.hInstance = g_hInstance;
                    g_ofn.lpstrFilter = szFilter;
                    g_ofn.lpstrFile = szFileName;
                    g_ofn.nMaxFile = MAX_PATH;
                    g_ofn.lpstrTitle = "Select File";
                    g_ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_LONGNAMES;

                    GetOpenFileName(&g_ofn);

                    if(szFileName[0] != 0)
                    {
                        SetWindowText(g_hEdit1,szFileName);
                    }
                }
            }

            if(wParam == 52)
            {
               ShellAbout(hwnd,"aPLib Pack","Joergen Ibsen's aPLib example",g_hIcon);
            }
            else if(wParam == 55)
            {
                ContPack = 0;
            }
            else if(wParam == 56)
            {
                killFlag = 1;
            }
        }
        break;
    case WM_SYSCOLORCHANGE:
        Do_ToolBar(hwnd);
        break;
    case WM_CREATE:
        Do_ToolBar(hwnd);
        g_hEdit1 = EditSl(NULL,20,100,253,22,hwnd,700);
        g_hButn1 = PushButton("...",283,100,25,22,hwnd,54);
        g_hStat1 = Static(NULL,20,127,240,20,hwnd,500);
        g_hButn2 = PushButton("stop",270,127,38,21,hwnd,55);
        hFont = (HFONT)GetStockObject(ANSI_VAR_FONT);

        SendMessage(g_hEdit1,WM_SETFONT,(WPARAM)hFont,0);
        SendMessage(g_hButn1,WM_SETFONT,(WPARAM)hFont,0);
        SendMessage(g_hStat1,WM_SETFONT,(WPARAM)hFont,0);
        SendMessage(g_hButn2,WM_SETFONT,(WPARAM)hFont,0);
        break;
    case WM_SIZE:
        SendMessage(g_hToolBar,TB_AUTOSIZE,0,0);
        break;

    case WM_DESTROY:
        PostQuitMessage(NULL);
        break;
    default:
        return DefWindowProc(hwnd,uMsg,wParam,lParam);

    }
    return 0;
}
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
     WNDCLASSEX wc;
    MSG        msg;
    DWORD      Wwd;
    DWORD      Wht;
    DWORD      Wtx;
    DWORD      Wty;

   

    InitCommonControls();
    g_hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(500));
   
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW;

    wc.lpfnWndProc = WindowProc;
    wc.cbClsExtra = NULL;
    wc.cbWndExtra = NULL;
    g_hInstance = hInstance;
    wc.hInstance = hInstance;
    wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = szClassName;
    wc.hIcon = g_hIcon;
    wc.hCursor = LoadCursor(NULL,IDC_ARROW);
    wc.hIconSm = g_hIcon;
    RegisterClassEx(&wc);

    Wwd = 334;
    Wht = 191;

    Wtx = (GetSystemMetrics(SM_CXSCREEN) - Wwd)/2;
    Wty = (GetSystemMetrics(SM_CYSCREEN) - Wht)/2;
   
    g_hWnd = CreateWindowEx(WS_EX_LEFT,szClassName,szDisplayName,
        WS_OVERLAPPEDWINDOW|WS_SYSMENU,Wtx,Wty,Wwd,Wht,
        NULL,NULL,hInstance,NULL);
   
    SetMenu(g_hWnd,LoadMenu(hInstance,MAKEINTRESOURCE(600)));
    ShowWindow(g_hWnd,SW_SHOWNORMAL);
    UpdateWindow(g_hWnd);

    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

分析:

由于我们用到了通用控件toolbarctrl,所以代码开头调用了 InitCommonControls();
接下来,我们看到,在窗口回调过程中WM_CREATE消息处理里面,动态的创建了窗体上的子窗口控件。

//创建Edit控件
HWND EditSl(CHAR *szDisplayName,DWORD x, DWORD y, DWORD wd,DWORD ht,HWND hParent,DWORD Editid)
{
    return CreateWindowEx(WS_EX_CLIENTEDGE,EditClass,szDisplayName,
                WS_VISIBLE | WS_CHILDWINDOW | ES_AUTOHSCROLL |ES_NOHIDESEL,
              x,y,wd,ht,hParent,(HMENU)Editid,g_hInstance,NULL);
}

//创建Button控件
HWND PushButton(CHAR *szDisplayName,DWORD x, DWORD y, DWORD wd,DWORD ht,HWND hParent,DWORD Btnid)
{
     return CreateWindowEx(0, btnClass,szDisplayName,
            WS_CHILD | WS_VISIBLE,
            x,y,wd,ht,hParent,(HMENU)Btnid,
            g_hInstance,NULL);
}

//创建标签static控件
HWND Static(CHAR *szDisplayName,DWORD x, DWORD y, DWORD wd,DWORD ht,HWND hParent,DWORD stcid)
{
    return CreateWindowEx(WS_EX_STATICEDGE,
            statClass,szDisplayName,
            WS_CHILD | WS_VISIBLE | SS_CENTER,
            x,y,wd,ht,hParent,(HMENU)stcid,
            g_hInstance,NULL);
}
下面我们重点看看工具条控件的创建。

//替换位图中的背景色
HBITMAP SetBmpColor (HBITMAP hBitmap)
{
    HDC mDC;
    HBRUSH hBrush;
    HBITMAP hOldBmp;
    HBITMAP hReturn;
    HBRUSH hOldBrush;

    mDC = CreateCompatibleDC(NULL);
    hOldBmp = (HBITMAP) SelectObject(mDC,hBitmap);

    hBrush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
    hOldBrush = (HBRUSH)SelectObject(mDC,hBrush);

    ExtFloodFill(mDC,1,1,GetPixel(mDC,1,1),FLOODFILLSURFACE);
    SelectObject(mDC,hOldBrush);
    DeleteObject(hBrush);

    hReturn = (HBITMAP)SelectObject(mDC,hBitmap);
    DeleteDC(mDC);
    return hReturn;
}

void Do_ToolBar(HWND hWnd)
{
    TBBUTTON tbb;
    TBADDBITMAP tbab;
    DWORD dwSize;
   
   //加载工具条按钮位图
    g_hTbBmp = LoadBitmap(g_hInstance,MAKEINTRESOURCE(750));

   //创建工具条控件
    g_hToolBar = CreateWindowEx(0,tbClass,szDisplayName,WS_CHILD |WS_VISIBLE|CCS_NODIVIDER | TBSTYLE_FLAT, 0,0,500,40,hWnd,NULL,g_hInstance,NULL);

   //设置 结构的大小
    SendMessage(g_hToolBar,TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON),0);

    //设置工具条按钮贴图的尺寸
    dwSize = 4915275; //75*75
    SendMessage(g_hToolBar,TB_SETBITMAPSIZE,0,dwSize);

    g_hTbBmp = SetBmpColor(g_hTbBmp);
    tbab.hInst = 0;   //低位字包含了第一个按钮位图的索引
    tbab.nID = (DWORD)g_hTbBmp;
   
    //TB_ADDBITMAP消息用来向工具栏中有效的图像列表中添加一个新的位图
    SendMessage(g_hToolBar,TB_ADDBITMAP,4,(LPARAM)&tbab);

   // 设置工具条按钮的尺寸
    SendMessage(g_hToolBar,TB_SETBUTTONSIZE,0,dwSize);

   //添加工具条按钮
    tbb.fsState = TBSTATE_ENABLED;
    tbb.dwData = 0;
    tbb.iString = 0;

    tbb.iBitmap = 0;
    tbb.idCommand = 50;
    tbb.fsStyle = TBSTYLE_BUTTON;
    SendMessage(g_hToolBar,TB_ADDBUTTONS,1,(LPARAM)&tbb);

    tbb.iBitmap = 1;
    tbb.idCommand = 51;
    tbb.fsStyle = TBSTYLE_BUTTON;
    SendMessage(g_hToolBar,TB_ADDBUTTONS,1,(LPARAM)&tbb);

    tbb.iBitmap = 2;
    tbb.idCommand = 52;
    tbb.fsStyle = TBSTYLE_BUTTON;
    SendMessage(g_hToolBar,TB_ADDBUTTONS,1,(LPARAM)&tbb);

    tbb.iBitmap = 3;
    tbb.idCommand = 53;
    tbb.fsStyle = TBSTYLE_BUTTON;
    SendMessage(g_hToolBar,TB_ADDBUTTONS,1,(LPARAM)&tbb);
}

最后介绍下ShellAbout这个api,我们可以使用它谈出系统级的提示框。
ShellAbout(hwnd,"aPLib Pack","Joergen Ibsen's aPLib example",g_hIcon);

原创粉丝点击