1. 程式人生 > >可用MinGW編譯的win32繪圖框架

可用MinGW編譯的win32繪圖框架

鑑於Microsoft Visual Studio體積巨大,我堅持不願意安裝,故在windows下程式設計一直都用MinGW和TCC作為編譯器,用Codebocks作為開發環境。MinGW對於C/C++標準庫支援很好,但是對於windows API就沒那麼好了。由於windows家族從win32API-> MFC->WPF->.net,體積龐大演變複雜,第三方庫顯然無法承載。
對於我個人工作,console下的操作使用標準庫函式已經足夠,檔案操作使用.bat批處理,網路操作使用Python,唯一需要win32系統函式的地方就是圖形介面了。這次在編寫botzone的貪吃蛇程式時,平臺規定用cpp+jsoncpp,為了方便除錯,只好使用MinGW呼叫win32API庫做一個簡單的繪圖框架。
由於GDI庫過於底層,使用起來很龐雜,我的思路是寫一個固定的框架程式碼,每隔30ms顯示某記憶體中的固定圖片(別忘了加鎖),其他所有的繪製過程都歸結到對於圖片的圖形繪製上去。這樣最大限度地隔離了win32系統。

首先建立基本的主入口和訊息迴圈函式WinMain:

#include <windows.h>
int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */ /* The Window structure */ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ /* Use Windows's default colour as the background of the window */ wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; /* Register the window class, and if it fails quit the program */ if (!RegisterClassEx (&wincl)) return 0; /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ "Double Snake Game Simulator", /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ 800, /* The programs width */ 600, /* and height in pixels */ HWND_DESKTOP, /* The window is a child-window to desktop */ NULL, /* No menu */ hThisInstance, /* Program Instance handler */ NULL /* No Window Creation data */ ); /* Make the window visible on the screen */ ShowWindow (hwnd, nCmdShow); /* Run the message loop. It will run until GetMessage() returns 0 */ while (GetMessage (&messages, NULL, 0, 0)) { /* Translate virtual-key messages into character messages */ TranslateMessage(&messages); /* Send message to WindowProcedure */ DispatchMessage(&messages); } /* The program return-value is 0 - The value that PostQuitMessage() gave */ return messages.wParam; }


訊息處理函式

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
    case WM_TIMER:
        RedrawWindow(hwnd,NULL,NULL,RDW_ERASE|RDW_INVALIDATE);
    case WM_PAINT:
    {

        PAINTSTRUCT ps;
        HDC hdc;
        RECT r;
        GetClientRect(hwnd,&r);

        EnterCriticalSection(&displock);

        hdc=BeginPaint(hwnd,&ps);

        DrawText(hdc,"Hello world",-1,&r,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
        EndPaint(hwnd,&ps);

        LeaveCriticalSection(&displock);

        printf("Paint%d!\n",num);
        break;
    }


    case WM_DESTROY:
        PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
        break;
    default:                      /* for messages that we don't deal with */
        return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}


為了不斷重繪,建立定時器

UINT_PTR WINAPI SetTimer(
    _In_opt_ HWND      hWnd,   //視窗控制代碼
    _In_     UINT_PTR  nIDEvent,  //定時器ID 使用者指定
    _In_     UINT      uElapse,  //定時時間ms
    _In_opt_ TIMERPROC lpTimerFunc  //回撥函式 NULL則送入訊息迴圈
    );

若在新建定時器時指定了nIDEvent,則可在訊息迴圈中判斷wParam的取值來區分定時器訊息源。本程式沒有用到這一特性。本程式程式碼為:

SetTimer(hwnd,1,20,NULL); 

並在訊息處理中新增一行

case WM_TIMER:
        //定時器操作

重繪視窗使用

BOOL WINAPI RedrawWindow(
  HWND hwnd,  //視窗控制代碼
  CONST RECT* lprcUpdate,  //重繪區域
  HRGN hrgnUpdate,  //重繪區域,優先
  UINT flags  //重繪標誌位
);

標誌位的設定大有講究。Win32的重繪概念比較複雜,將視窗標為invalid和生成WM_PAINT訊息是兩個過程,此外還有WM_ERASEBKGND訊息作為前導。
本程式中使用

RedrawWindow(hwnd,NULL,NULL,RDW_ERASE|RDW_INVALIDATE)
RedrawWindow(hwnd,NULL,NULL,RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW)

結果一樣。但是如果漏掉了前兩個引數,則WM_PAINT訊息仍會產生並執行相應重繪程式碼,但重繪後窗口介面不會更新,只有最小化或被遮擋後才行。

建立執行緒使用

HANDLE WINAPI CreateThread(
  _In_opt_  LPSECURITY_ATTRIBUTES  lpThreadAttributes=NULL,
  _In_      SIZE_T                 dwStackSize=0,
  _In_      LPTHREAD_START_ROUTINE lpStartAddress,
  _In_opt_  LPVOID                 lpParameter=NULL,
  _In_      DWORD                  dwCreationFlags=0,
  _Out_opt_ LPDWORD                lpThreadId=NULL
);

若呼叫了C庫函式,則應使用

uintptr_t _beginthread( // NATIVE CODE
   void( __cdecl *start_address )( void * ),
   unsigned stack_size,
   void *arglist 
);

本程式中,我使用

_beginthread(ThreadFunction,0,NULL);

其中執行函式ThreadFunction形式為

void ThreadFunction(void* pParam)
{
   //running code
}

退出執行緒使用

ExitThread();
_endthread();

建立臨界區使用

CRITICAL_SECTION displock;

初始化

InitializeCriticalSection(&displock);

進入臨界區

EnterCriticalSection(&displock);

離開臨界區

LeaveCriticalSection(&displock);

釋放資源

DeleteCriticalSection(&displock);

在WM_PAINT中:

  • 清除背景
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW));
  • 選擇畫筆(用於畫線)
HPEN hBluePen = CreatePen(PS_SOLID, 1, RGB(200, 0, 80));        //筆型 粗細 顏色
HPEN hOldPen = (HPEN)SelectObject(hdc, hBluePen);       //返回老畫筆
/********使用畫筆**********/
SelectObject(hdc, hOldPen);     //設定回原畫筆
DeleteObject(hBluePen);     //釋放資源
  • 選擇畫刷(用於填充)
HBRUSH hPurpleBrush = CreateSolidBrush(RGB(255, 0, 255));
    /********使用畫刷***********/
    FillRect(hdc, &lprc, hPurpleBrush);
DeleteObject(hPurpleBrush);

畫線

hdc = BeginPaint(hWnd, &ps);
MoveToEx(hdc, 60, 20, NULL);
LineTo(hdc, 264, 122);
EndPaint(hWnd, &ps);

折線

BOOL Polyline(HDC hdc, CONST POINT *lppt, int cPoints);
POINT Pt[7];
Pt[0].x = 20;  Pt[0].y = 50;
Pt[1].x = 180; Pt[1].y = 50;
Pt[2].x = 180; Pt[2].y = 20;

hdc = BeginPaint(hWnd, &ps);
Polyline(hdc, Pt, 3);
EndPaint(hWnd, &ps);

繪製矩形

PAINTSTRUCT ps;
HDC hdc;
RECT lprc;
//GetClientRect(hwnd,&lprc);  獲取視窗矩形大小
SetRect(&lprc,1,1,800,600);  //left up right down
hdc=BeginPaint(hwnd,&ps);
FillRect(hdc, &lprc, (HBRUSH) (1));
EndPaint(hwnd,&ps);

繪製記憶體中的圖片
需要使用Bitmap,概念也比較複雜。Bitmap可分為裝置無關DIB和裝置相關DDB兩種,DDB是和dc相關的點陣圖,不同情況下用CreateBMP(),CreateCompatibleBMP(),LoadBMP(),LoadImage()等建立的就是DDB。DIB就是一片記憶體,裡面儲存著點陣圖掐頭去尾,只留下RGB,或者畫素+色板的資訊。
Bitmap屬於一種GDI物件,同Brushes Fonts Paths Pens Regions等物件一樣,可以被指定到GDI目標裝置context上。

以下函式從影象畫素矩陣建立DDB控制代碼

HBITMAP CreateBitmap(
  _In_  int  nWidth,  //點陣圖寬度
  _In_  int  nHeight,  //點陣圖高度
  _In_  UINT cPlanes,  //該裝置使用的顏色位面數目
  _In_  UINT cBitsPerPel,   //點顏色位數
  _In_  const VOID *lpvBits  //資料指標 
);

對於彩色影象,用以下函式不需要型別轉換步驟,速度更快:

HBITMAP CreateCompatibleBitmap(HDC hdc,int nWidth,int nHeight);

為了防止螢幕閃爍,新建DC上下文應用雙緩衝機制。

HDC CreateCompatibleDC(
  HDC hdc
); 

將DC與Bitmap繫結

HDC memdc=CreateCompatibleDC(hdc);
HBITMAP memBmp=CreateCompatibleBitmap(hdc,
                GetSystemMetrics(SM_CXSCREEN),
                GetSystemMetrics(SM_CYSCREEN));
SelectObject(memdc,memBmp);

將緩衝區資料複製到DIB

int SetDIBits(
  _In_  HDC        hdc,  //裝置控制代碼
  _In_  HBITMAP    hbmp,  //點陣圖控制代碼
  _In_  UINT       uStartScan,  //開始行=0
  _In_  UINT       cScanLines,  //行數
  _In_  const VOID       *lpvBits,  //畫素資料陣列
  _In_  const BITMAPINFO *lpbmi,  //指向DIB資訊的資料結構
  _In_  UINT       fuColorUse=DIB_RGB_COLORS
);

從DIB複製到緩衝區資料.
若lpvBits=NULL且BITMAPINFO中的biBitCount成員被初始化為零,binfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER),則當前顯示裝置屬性將被輸出。

int GetDIBits(
  _In_     HDC          hdc,
  _In_     HBITMAP      hbmp,
  _In_     UINT         uStartScan,
  _In_     UINT         cScanLines,
  _Out_    LPVOID       lpvBits,
  _Inout_  LPBITMAPINFO lpbi,
  _In_     UINT         uUsage
);

其中,BITMAPINFO定義了DIB的維度和顏色資訊

typedef struct tagBITMAPINFO {
  BITMAPINFOHEADER bmiHeader;
  RGBQUAD          bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;

typedef struct tagBITMAPINFOHEADER {
  DWORD biSize;  //自身大小
  LONG  biWidth;  //寬度
  LONG  biHeight;  //高度
  WORD  biPlanes=1; 
  WORD  biBitCount;  //位深度
  DWORD biCompression;  //壓縮方式 一般BI_RGB
  DWORD biSizeImage;  //假如不是BI_JPEG或BI_PNG,設為0即可
  LONG  biXPelsPerMeter;  //畫素密度
  LONG  biYPelsPerMeter;  //畫素密度
  DWORD biClrUsed=0;
  DWORD biClrImportant=0;
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;

typedef struct tagRGBQUAD {
  BYTE rgbBlue;
  BYTE rgbGreen;
  BYTE rgbRed;
  BYTE rgbReserved;
} RGBQUAD;


以下是繪製圖片的程式碼

    HDC memdc=CreateCompatibleDC(hdc);
        HBITMAP memBmp=CreateCompatibleBitmap(hdc,
                        GetSystemMetrics(SM_CXSCREEN),
                        GetSystemMetrics(SM_CYSCREEN));
        SelectObject(memdc,memBmp);

        BITMAPINFO binfo;
        ZeroMemory(&binfo,sizeof(BITMAPINFO));
        binfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
        binfo.bmiHeader.biBitCount=32;
        binfo.bmiHeader.biCompression=0;
        binfo.bmiHeader.biWidth=SCREEN_W;
        binfo.bmiHeader.biHeight=SCREEN_H;
        binfo.bmiHeader.biPlanes=1;
        binfo.bmiHeader.biSizeImage=0;

        BYTE *pBuf=new BYTE[SCREEN_H*SCREEN_W*4];
        int row_size=SCREEN_W*4;
        for(int i=0;i<SCREEN_H;i++)
            pBuf[i*row_size+i*4]=200;

        SetDIBits(memdc,memBmp,0,
                  binfo.bmiHeader.biHeight,
                  pBuf,(BITMAPINFO*)&binfo,
                  DIB_RGB_COLORS);
        BitBlt(hdc, 0, 0, binfo.bmiHeader.biHeight, binfo.bmiHeader.biWidth,memdc, 0, 0, SRCCOPY);

        DeleteDC(memdc);
        DeleteObject(memBmp);

按照以上程式碼執行,發現重繪閃爍嚴重這個網站給出了全面的解決辦法。
主要問題在於windows的重繪分為兩個階段

  • WM_ERASEBKGND訊息:清除背景
  • WM_PAINT: 繪製新內容

這樣,在響應兩個訊息之間的間隔,螢幕為白板,從而發生閃爍。解決方法有以下兩種:

  • 在WM_ERASEBKGND響應程式碼中返回非零值
case WM_ERASEBKGND:
    return 1;
  • 將視窗的背景刷設為NULL
wincl.hbrBackground=0;


此外,當繪製物件過多時,必須新增雙緩衝,否則將可見影象重新整理過程。典型的雙緩衝過程如下:

HDC          hdcMem;
HBITMAP      hbmMem;
HANDLE       hOld;

PAINTSTRUCT  ps;
HDC          hdc;
....
case WM_PAINT:

    // Get DC for window
    hdc = BeginPaint(hwnd, &ps);

    // Create an off-screen DC for double-buffering
    hdcMem = CreateCompatibleDC(hdc);
    hbmMem = CreateCompatibleBitmap(hdc, win_width, win_height);

    hOld   = SelectObject(hdcMem, hbmMem);
    /*********Draw into hdcMem here*************/

    /*********Draw into hdcMem here*************/
    // Transfer the off-screen DC to the screen
    BitBlt(hdc, 0, 0, win_width, win_height, hdcMem, 0, 0, SRCCOPY);

    // Free-up the off-screen DC
    SelectObject(hdcMem, hOld);
    DeleteObject(hbmMem);
    DeleteDC    (hdcMem);
    EndPaint(hwnd, &ps);

至此基本解決了閃爍問題

鍵盤相應

case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_UP:
            SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, 0);
            break;

        case VK_DOWN:
            SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, 0);
            break;

        case VK_LEFT:
            SendMessage(hwnd, WM_HSCROLL, SB_PAGEUP, 0);
            break;

        case VK_RIGHT:
            SendMessage(hwnd, WM_HSCROLL, SB_PAGEDOWN, 0);
            break;
        }
    break;

以下是總體程式碼

BYTE *pBuf=new BYTE[SCREEN_H*SCREEN_W*4];
int row_size=SCREEN_W*4;
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
    case WM_CREATE:
        ZeroMemory(pBuf,SCREEN_H*SCREEN_W*4);
        for(int i=0;i<SCREEN_H;i++)
            pBuf[i*row_size+i*4]=200;
        break;
    case WM_TIMER:
        RedrawWindow(hwnd,NULL,NULL,RDW_ERASE|RDW_INVALIDATE);
        break;
    case WM_PAINT:
    {

        PAINTSTRUCT ps;
        HDC hdc;
        RECT lprc;

        EnterCriticalSection(&displock);
        hdc=BeginPaint(hwnd,&ps);


            //清除背景

            FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW));
            HPEN hBluePen = CreatePen(PS_SOLID, 10, RGB(200, 0, 80));
            HPEN hPen = (HPEN)SelectObject(hdc, hBluePen);

            MoveToEx(hdc, 100, 100, NULL);
            LineTo(hdc, num, 2*num);

            SelectObject(hdc, hPen);
            DeleteObject(hBluePen);

            HBRUSH hPurpleBrush = CreateSolidBrush(RGB(255-num, num, 20));
            SetRect(&lprc,600,400,650,450);
            FillRect(hdc, &lprc, hPurpleBrush);
            DeleteObject(hPurpleBrush);

            //checkScreenProperty(hdc);
        HDC memdc=CreateCompatibleDC(hdc);
        HBITMAP memBmp=CreateCompatibleBitmap(hdc,
                        GetSystemMetrics(SM_CXSCREEN),
                        GetSystemMetrics(SM_CYSCREEN));
        SelectObject(memdc,memBmp);

        BITMAPINFO binfo;
        ZeroMemory(&binfo,sizeof(BITMAPINFO));
        binfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
        binfo.bmiHeader.biBitCount=32;
        binfo.bmiHeader.biCompression=0;
        binfo.bmiHeader.biWidth=SCREEN_W;
        binfo.bmiHeader.biHeight=SCREEN_H;
        binfo.bmiHeader.biPlanes=1;
        binfo.bmiHeader.biSizeImage=0;


        SetDIBits(memdc,memBmp,0,
                  binfo.bmiHeader.biHeight,
                  pBuf,(BITMAPINFO*)&binfo,
                  DIB_RGB_COLORS);
        BitBlt(hdc, 0, 0, binfo.bmiHeader.biWidth, binfo.bmiHeader.biHeight,memdc, 0, 0, SRCCOPY);

        DeleteDC(memdc);
        DeleteObject(memBmp);

        GetClientRect(hwnd,&lprc);
        DrawText(hdc,"Hello World",-1,&lprc,DT_SINGLELINE|DT_CENTER|DT_VCENTER);

        EndPaint(hwnd,&ps);
        LeaveCriticalSection(&displock);
        break;
    }


    case WM_DESTROY:
        running=false;
        PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
        break;
    default:                      /* for messages that we don't deal with */
        return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

總結與吐槽

微軟網頁上的這段典型程式碼體現出GDI有多麼冗繁而反人類。
由於從一開始就沒有面向物件的概念,所以各種變數資料裸露在外,大量名稱交錯使用,很容易造成混亂。給程式設計師的記憶負擔也很重。

相關推薦

可用MinGW編譯win32繪圖框架

鑑於Microsoft Visual Studio體積巨大,我堅持不願意安裝,故在windows下程式設計一直都用MinGW和TCC作為編譯器,用Codebocks作為開發環境。MinGW對於C/C++標準庫支援很好,但是對於windows API就沒那麼好了。

MinGW編譯Win32 GDI應用程式

用來編譯的批處理 del *.o gcc -c *.cpp -Wno-write-strings windres Resource.rc Resource.o g++ *.o -o Gomoku.exe -s -lgdi32 -luser32 -lkern

mp4v2使用mingw編譯配置

dllexport win32 cygwin col back dll amp import 部分 備註:黃色部分為原始語句,紅色部分為修改後的語句   ‘-’表示去掉,‘+’表示增加 1.修改configure文件 1)去掉enable_shared=no *-*-mi

[X264] MinGW編譯x264,VC中調用libx264.dll-------------<參考轉>

-1 bin文件 source color turn 9.4 make int lease 1. 下載並按照MinGW,最好就缺省按照 http://sourceforge.net/projects/ ... ler/mingw-get-inst/ 把C:\Mi

Win32程序框架

post show nts zcl nap pda wndproc sna char #include<Windows.h> LRESULT CALLBACK WindowProc(HWND,UINT,WPARAM,LPARAM); int WINAPI

iOS繪圖框架CoreGraphics分析

png 保存 alloc opengl-es div 運行 dell .html shc 由於CoreGraphics框架有太多的API,對於初次接觸或者對該框架不是十分了解的人,在繪圖時,對API的選擇會感到有些迷茫,甚至會覺得iOS的圖形繪制有些繁瑣。因此,本文主要介紹

MinGW 編譯 libaom 1.0.0 註意事項

bsp lib class fig har 註意事項 pre ble nor CMake 後不生成 config/aom_version.h 文件 需要手動編寫 #define VERSION_MAJOR 1 #define VERSION_MINOR 0 #define

Clion使用MinGW編譯好的boost庫

party uil roo con build nat 命令行 dha -s MinGW編譯Boost庫可以參考我之前寫的編譯Boost的文章。 以下是cmake鏈接boost靜態庫的配置: 1 cmake_minimum_required(VERSION 3.8)

Windows使用mingw編譯openblas

系統環境:win10 軟體環境: (1)mingw 5.3,使用Qt5.11.1自帶的 (2)OpenBLAS-0.2.20 (3)Armadillo9.1 幾點說明: (1)關於openblas在window下的使用多是介紹其window的預編譯版,使用VS編譯器,但筆者強迫症嚴重

關於mingw編譯Qt時無法編譯opengl es2(ANGLE)版本的問題

  最近在使用mingw64(gcc 8.1.0)編譯Qt5.12.0時,發現config總是檢測opengl es2不通過,雖然可以使用opengl desktop,但根據qt官方的建議,如果不直接使用opengl函式,還是使用opengl es2版本相容性更好,而且opengl es2和qt自帶

QT中使用MinGW 編譯的protobuf庫--包含庫的生成和使用

0前言 最近要在QT中使用protobuf,於是需要編譯protobuf靜態庫檔案,匯入qt使用,沒想到過程非常曲折,各種報錯各種坑,在網上參考了很多文章,最後終於成功了,現在將QT中使用protobuf的整個配置過程都寫出來提供給大家,希望能夠幫助到大家。

mingw編譯ffmpeg

一、安裝mingw 二、下載ffmpeg 去官網下ffmpeg原始碼tar包 三、 編譯ffmpeg 執行mingw指令碼“msys.bat”進入shell,路徑為: C:\MinGW\msys\1.0 下載yasm的windows版本編

QT5.10開發(2) 在Windows 10下使用MinGW編譯 靜態Qt 5.10 release版 詳細過程

Qt建議安裝動態連結Dbug版和編譯安裝靜態連結release版前提: 先安裝動態連結Dbug版,方法:QT5.10開發(1)安裝QT5.10 地址:http://blog.csdn.net/qq_15304853/article/details/79165301 然後編譯

【POCO】POCO學習總結(四)——MinGW編譯poco

在window下使用MinGW編譯poco 使用MSYS 下載MSYS 安裝 執行mingw-get-setup.exe,只選擇安裝msys-base(mingw我使用Qt中自帶的) 配置 開啟C:\MinGW\msys\1.0\ms

MinGW編譯c++,中文顯示亂碼解決方案

我比較喜歡MinGW,現在使用的是 C:\WINDOWS\system32>gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_

Windows環境下使用minGW編譯boost庫(windows下編譯使用asio, thread等)

我在windows下沒有用vs進行開發, 而是安裝mingw+eclipse. 根據官網介紹, boost庫中, 一些庫無需編譯即可使用, 而有一些類庫, 如 asio, thread都是與平臺有關的, 所以需要編譯後才能使用.  根據官網想到, 在linux下面編譯安裝

使用 MinGW 編譯 ZeroMQ 靜態庫

最近折騰zeromq,嘗試用 MinGW 來編譯了一下。 根據 http://zeromq.org/build:mingw 的說明,用MinGW來編譯 ZeroMQ 自然是沒有問題的。但是業餘測試一些簡單的程式碼還是用靜態庫比較方便。怎奈何,預設的 configure

mingw編譯librtmp

1  下載 MinGW和MSYS:http://www.mingw.org/ zlib:http://www.zlib.net/ openSSL:http://www.openssl.org/ ActiveState Perl:http://www.perl.org/ rt

mingw 編譯opencv

                                 使用MinGW編譯OpenCV庫 系統環境與資源 MinGW編譯器目錄:TDM-GCC版,位於D:\complicer\MinGW OpenCV原始碼目錄:D:\mysoftware\opensource\opencv OpenCV

Linphone 3.7.0 for mingw 編譯安裝

前言      接著講這個,前面在mingw上成功編譯了linphone 3.5.2版本,執行基本都沒發現有問題。後面就開始編譯最新版本linphone,編譯這個第一步是必須獨自編譯安裝belle-sip 1.3.0,編譯這個必須先編譯安裝antlr 相應版本(官方文件寫的