zoukankan      html  css  js  c++  java
  • 基于SOUI开发一个简单的小工具

    基于DriectUI有很多库,比如

    Duilib (免费)

    soui (免费)

    DuiVision (免费)

    炫彩 (界面库免费,UI设计器付费,不提供源码)

    skinui (免费使用,但不开放源码,仅支持 VS 2013)

    Duilib 很久不维护了,而很多不同的分支,似乎都不太维护。微信 Windows 的版本是基于 Duilib 进行开发的,说明应该还是很广泛的。

    我当时最倾向于 DuiVision,界面很漂亮,代码也是上述库里面最简洁的。唯一的问题主是窗口最小化之后,再打开,会黑一下。(今天写这篇文章的时候,发现已经有人 fix 这个 bug了https://github.com/blueantst/DuiVision/issues/61

    soui 的性能是上述库里面最好的,优化的非常好(动画与 list 一点都不卡)。上手和API设计不如 DuiVision,但比较全面,而且一直在更新,应用列表也比 DuiVision 要多一些。我拿它做了一个简单的上应用,校验CRC。

    最开始的第一个版本,当文件较大时,会卡一会。之后我加入线程,保证主线程是不被卡住的。

    对于C++我没有开发过完整的项目,只是原来弄 Cocos2d 的时候接触过C++,也忘记差不多了。写这个工具,半摸索半调试,也达到了自己想要的目的。

    待此记录一下遇到的几个问题,算是 C++ 的笔记。

    Crc的校验使用了分段循环读取,这个技巧在面对大文件读写时很有用,防止一次申请过大的内存(特别是手机对内存比较敏感的设备)。

    Crc.h

    #ifndef CRC32_H_
    #define CRC32_H_
    
    # include <stdio.h>
    # include <stdlib.h>
    
    # define CRC_BUFFER_SIZE  4096
    
    class Crc32
    {
    public:
        typedef void(*FUNC)(FILE *file, unsigned int *outCrc32, int nReturnVal, void *dlg);
    
        static int GetCRC(FILE *file, unsigned int *outCrc32, void *dlg = NULL, FUNC callbackFn = NULL);
    };
    
    
    #endif

    Crc.cpp

    /*----------------------------------------------------------------------------*
     *  CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
     *
     *  This program generates the CRC-32 values for the files named in the
     *  command-line arguments.  These are the same CRC-32 values used by GZIP,
     *  PKZIP, and ZMODEM.  The Crc32_ComputeBuf() can also be detached and
     *  used independently.
     *
     *  THIS PROGRAM IS PUBLIC-DOMAIN SOFTWARE.
     *
     *  Based on the byte-oriented implementation "File Verification Using CRC"
     *  by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67.
     *
     *  v1.0.0: original release.
     *  v1.0.1: fixed printf formats.
     *  v1.0.2: fixed something else.
     *  v1.0.3: replaced CRC constant table by generator function.
     *  v1.0.4: reformatted code, made ANSI C.  1994-12-05.
     *  v2.0.0: rewrote to use memory buffer & static table, 2006-04-29.
     *  v2.1.0: modified by Nico, 2013-04-20
    *----------------------------------------------------------------------------*/
    #include "stdafx.h"
    #include "Crc.h"
    
    /*----------------------------------------------------------------------------*
     *  NAME:
     *     Crc32_ComputeBuf() - computes the CRC-32 value of a memory buffer
     *  DESCRIPTION:
     *     Computes or accumulates the CRC-32 value for a memory buffer.
     *     The 'inCrc32' gives a previously accumulated CRC-32 value to allow
     *     a CRC to be generated for multiple sequential buffer-fuls of data.
     *     The 'inCrc32' for the first buffer must be zero.
     *  ARGUMENTS:
     *     inCrc32 - accumulated CRC-32 value, must be 0 on first call
     *     buf     - buffer to compute CRC-32 value for
     *     bufLen  - number of bytes in buffer
     *  RETURNS:
     *     crc32 - computed CRC-32 value
     *  ERRORS:
     *     (no errors are possible)
    *----------------------------------------------------------------------------*/
    
    static unsigned int Crc32_ComputeBuf(unsigned int inCrc32, const void *buf, size_t bufLen) {
        static const unsigned int crcTable[256] = {
         0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,
         0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,
         0xE7B82D07,0x90BF1D91,0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,
         0x6DDDE4EB,0xF4D4B551,0x83D385C7,0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,
         0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,0x3B6E20C8,0x4C69105E,0xD56041E4,
         0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C,
         0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,0x26D930AC,
         0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F,
         0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,
         0xB6662D3D,0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,
         0x9FBFE4A5,0xE8B8D433,0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,
         0x086D3D2D,0x91646C97,0xE6635C01,0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,
         0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950,0x8BBEB8EA,
         0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65,0x4DB26158,0x3AB551CE,
         0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB,0x4369E96A,
         0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,
         0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,
         0xCE61E49F,0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,
         0xB7BD5C3B,0xC0BA6CAD,0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,
         0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,
         0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,0xF00F9344,0x8708A3D2,0x1E01F268,
         0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0,
         0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,0xD6D6A3E8,
         0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B,
         0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,
         0x4669BE79,0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,
         0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,
         0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,
         0x9C0906A9,0xEB0E363F,0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE,
         0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,0x86D3D2D4,0xF1D4E242,
         0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,0x88085AE6,
         0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45,
         0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,
         0x3E6E77DB,0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,
         0x47B2CF7F,0x30B5FFE9,0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,
         0xCDD70693,0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,
         0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D
        };
        unsigned int crc32;
        unsigned char *byteBuf;
        size_t i;
    
        /** accumulate crc32 for buffer **/
        crc32 = inCrc32;
        byteBuf = (unsigned char*)buf;
    
        for (i = 0; i < bufLen; i++) {
            crc32 = ((crc32 >> 8) & 0x00FFFFFF) ^ crcTable[(crc32 ^ byteBuf[i]) & 0xFF];
        }
    
        return crc32;
    }
    
    /*----------------------------------------------------------------------------*
     *  NAME:
     *     Crc32_ComputeFile() - compute CRC-32 value for a file
     *  DESCRIPTION:
     *     Computes the CRC-32 value for an opened file.
     *  ARGUMENTS:
     *     file - file pointer
     *     outCrc32 - (out) result CRC-32 value
     *  RETURNS:
     *     err - 0 on success or -1 on error
     *  ERRORS:
     *     - file errors
    *----------------------------------------------------------------------------*/
    
    int Crc32::GetCRC(FILE *file, unsigned int *outCrc32, void *dlg, FUNC callbackFn) {
        unsigned char buf[CRC_BUFFER_SIZE];
        size_t bufLen;
    
        /** accumulate crc32 from file **/
        *outCrc32 = 0;
    
        unsigned int crc = 0xFFFFFFFF;
    
        while (1) {
            bufLen = fread(buf, 1, CRC_BUFFER_SIZE, file);
            if (bufLen == 0) {
                if (ferror(file)) {
                    fprintf(stderr, "error reading file
    ");
    
                    if (callbackFn != NULL)
                    {
                        callbackFn(file, outCrc32, -1, dlg);
                    }
    
                    return -1;
                }
                break;
            }
            crc = Crc32_ComputeBuf(crc, buf, bufLen);
        }
    
        *outCrc32 = crc ^ 0xFFFFFFFF;
    
        if (callbackFn != NULL)
        {
            callbackFn(file, outCrc32, 0, dlg);
        }
    
        return 0;
    }

    “选择文件”用了 soui 提供的方法

    CFileDialogEx openDlg(TRUE, _T("pkg"), 0, 6, _T("pkg files(*.pkg)*.pkgAll files (*.*)*.*"));
    if (openDlg.DoModal() == IDOK)
    {
        //openDlg.m_szFileName
        SRichEdit *pEdit = FindChildByName2<SRichEdit>(L"ipt_select_file");
    
        //SStringW strValue = S_CT2W(pEdit->GetWindowText());
        pEdit->SetWindowTextW(openDlg.m_szFileName);
    }
    class CFileDialogEx
    {
    public:
    
        OPENFILENAME m_ofn;
        BOOL m_bOpenFileDialog;            // TRUE for file open, FALSE for file save
        TCHAR m_szFileTitle[_MAX_FNAME];   // contains file title after return
        TCHAR m_szFileName[_MAX_PATH];     // contains full path name after return
    
        CFileDialogEx(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
            LPCTSTR lpszDefExt = NULL,
            LPCTSTR lpszFileName = NULL,
            DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT ,
            LPCTSTR lpszFilter = NULL,
            HWND hWndParent = NULL)
        {
            memset(&m_ofn, 0, sizeof(m_ofn)); // initialize structure to 0/NULL
            m_szFileName[0] = _T('');
            m_szFileTitle[0] = _T('');
    
            m_bOpenFileDialog = bOpenFileDialog;
            m_ofn.lStructSize = sizeof(m_ofn);
            m_ofn.lpstrFile = m_szFileName;
            m_ofn.nMaxFile = _MAX_PATH;
            m_ofn.lpstrDefExt = lpszDefExt;
            m_ofn.lpstrFileTitle = (LPTSTR)m_szFileTitle;
            m_ofn.nMaxFileTitle = _MAX_FNAME;
            m_ofn.Flags = dwFlags | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLESIZING| OFN_NOCHANGEDIR;
            m_ofn.lpstrFilter = lpszFilter;
            m_ofn.hwndOwner = hWndParent;
    
            // setup initial file name
            if(lpszFileName != NULL)
                _tcscpy_s(m_szFileName, _countof(m_szFileName), lpszFileName);
        }
    
        INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
        {
            if(m_ofn.hwndOwner == NULL)   // set only if not specified before
                m_ofn.hwndOwner = hWndParent;
    
            if(m_bOpenFileDialog)
                return ::GetOpenFileName(&m_ofn);
            else
                return ::GetSaveFileName(&m_ofn);
        }

    而 C++ 11的线程,回调函数不能传实际类方法(会报“无法从 overloaded-function ….”)。我做了一个转化,定义一个静态类方法,然后将 this 回传,再调用this的实例方法。

    static void CrcCallback(FILE *file, unsigned int *outCrc32, int nReturnVal, void *dlg);
    std::thread t(&Crc32::GetCRC, file, outCrc32, this, &CMainDlg::CrcCallback);
    t.detach();

    中间相当于加了一个 proxy,将 this 传给 Crc::GetCRC 方法。

    学到的另外一个技巧就是通过 typedef 来定义函数指针:typedef 返回类型(*新类型)(参数列表)

    不得不说 C++ 11 的 thread 使用起来真的是非常方便和简单 微笑

  • 相关阅读:
    微信小程序HTTPS
    微信商城-1简介
    va_list
    Event log c++ sample.
    EVENT LOGGING
    Analyze Program Runtime Stack
    unknow table alarmtemp error when drop database (mysql)
    This application has request the Runtime to terminate it in an unusual way.
    How to check if Visual Studio 2005 SP1 is installed
    SetUnhandledExceptionFilter
  • 原文地址:https://www.cnblogs.com/meteoric_cry/p/9959352.html
Copyright © 2011-2022 走看看