《深入浅出mfc》 第1章 笔记

简介: 需要什么函数库(.lib) windows支持动态链接库,应用程序所调用 的windows api 函数是在“执行期间“才链接上的。Windows程序调用 可以分为 C Runtimes以及windows api 大概两部分。

需要什么函数库(.lib)

windows支持动态链接库,应用程序所调用 的windows api 函数是在“执行期间“才链接上的。Windows程序调用 可以分为 C Runtimes以及windows api 大概两部分。早期的C Runtimes并不支持动态链接,vc++ 4.0之后已经支持。并且在32位已不在拥有small/medium/large等内存模式之分。

LIBC.lib:这是c Runtime函数库的静态版本
MSVCRT.lib:这是 c Runtime函数的动态库版本(MSVCRT40.dll)的import函数库。程序运行期间必须有MSVCRT40.dll在场。

另一组函数Windows Api由操作系统本身提供(GDI32.dll、USER32.DLL,Kernel32.DLL)。虽说动态链接库是在执行期间发生的。但是链接器仍需要先为调用者准备一些适当的信息。这些适当的信息放在”import函数库”,32位的windows的三大模块对应的 import函数库分别为GDI32.lib user32.lib kernel32.lib。

消息映射的雏形

《windows程序设计》里面的消息循环(WndPorc) switch case 语句 如下

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // 分析菜单选择:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: 在此添加任意绘图代码...
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

为了把窗口函数设计一旬模块化,一般化。下面是一种做法。

//首先定义一个MSGMAP_ENTRY结构和一个dim宏
struct MSGMAP_ENTRY
{
    UINT nMessage;
    LONG (*pfn)(HWND ,UINT,WPARAM,LPARAM);
};
#define dim(x) (sizeof(x)/sizeof(x[0]))

//把欲处理的消息以及消息处理全程关联性建立起来
struct MSGMAP_ENTRY _messageEntries[] = 
{
    WM_CREATE,OnCreate,
    WM_PAINT,OnPaint,
    WM_SIZE,OnSize,
    WM_COMMAND,OnCommand,
    WM_SETFOCUS,OnSetFocus,
    WM_CLOSE,OnClose,
    WM_DESTROY,OnDestroy
};

//Command-ID 与处理全程之间对照表格
struct MSGMAP_ENTRY _commandEntries[] = 
{
    IDM_ABOUT,OnAbout,
    IDM_EXIT,OnExit
};


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int i;
    for(i = 0;i < dim(_messageEntries);i++)
        if(message == _messageEntries[i].nMessage)
            return (*_messageEntries[i].pfn)(hWnd,message,wParam,lParam);
    return DefWindowProc(hWnd,message,wParam,lParam);
}

LONG OnCommand(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    for(int i =0;i<dim(_commandEntries);i++)
        if(LOWORD(wParam) == _commandEntries[i].nMessage)
            return (*_commandEntries[i].pfn)(hWnd,message,wParam,lParam);
    return DefWindowProc(hWnd,message,wParam,lParam);
}

LONG OnCreate(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
}

LONG OnAbout(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
}

...

这样WndPorc和OnCommand永远不变。每当处理新消息的时候给结构体里面加元素就行了

Windows 程序的生与死

windows程序生与死\

空间时间的处理OnIdle

空间时间是指”系统中没以任何消息等待处理“的时间。空间时间常常发生,不要认为你鼠标移动时产生一大堆WM_MOUSEMOVE消息,事实上夹杂在每一个WM_MOUSEMOVE之间就可能存在许多空间时间。毕竟,计算机速度超乎想象。

后台工作最适宜在空闲时间做,传送sdk程序如果要处理空间时间,可以以下循环取代WinMain中的消息循环。

while(TRUE)
{
    if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
    {
        if(mes.message == WM_QUIT)
            break;
        TranslateMessage(&msg);
        DispatchMessage(&msg)
    }
    else
        OnIdle();
}

什么是 C Runtime 函数库的多线程版本

当 C Runtime函数库与20世纪70年代出来时 pc 容量很少,多任务是个新奇观念,更别提多线程了。因此当时产品基础所演化的 c runtime函数库在多线程的表现上出现了严重问题。无法被多线程程序调用 。
利用更种同步机制 如 critcal section mutex semaphore event 可以重新开发一套支持多线程的runtime 函数库。问题是加上这样的能力可能导致程序代码大小和执行效率都遭受不良的波及----即使你只激活了一个线程。

VC++的折衷方案是提供两种版本的 c runtime函数库。一种版本给单线程使用,一种版本给多线程程序使用。多线程版本的重大改变是第一、变量加errno者现在变成每个线程拥有一个,第二、多线程版本中的数据结构同步机制加以保护 。

Vc++一共有六个 c runtime函数库产品供您选择

  • Single-Threaded(static) libc.lib
  • Mutithreaded(static)   libcmt.lib
  • mutithread dll msvcrt.lib
  • debug single-threaded(static) libcd.lib
  • debug mutithreaded(static) libcmtd.lib
  • debug mutithread dll msvcrtd.lib

VC++编译器提供以下选项,让我们决定使用哪一个 c runtime函数库

  • /ML Single-threaded(static)
  • /MT Mutithread (static)
  • /MD Mutithread dll (dynamic import libray)
  • /MLD debug single-thread(static)
  • /MTD debug mutithread(static)
  • /MDD debug mutithread dll(dynamic import libray)

 

相关文章
|
分布式数据库 Windows
|
消息中间件 程序员 开发工具
进入MFC讲坛的前言(一)
在这里,我想谈谈自己学习MFC的一些体会。我是从1997年才开始在Window下编写程序的。在这之前,我编写过一些DOS程序,包括一个简单的全屏幕编辑器和一个带函数的表达式解释器,都是一些小的程序。Window 3.1流行后,我开始在它下面编写程序。
901 0
|
消息中间件 程序员
进入MFC讲坛的前言(二)
MFC的WinMain   使用MFC编程的程序员刚开始都会提出这样一个问题:我的程序是从哪儿开始执行的?回答是:从WinMain()开始执行的。提出这样的问题是由于在他们所编写的MFC应用中看不到WinMain()函数。
804 0
进入MFC讲坛的前言(四)
MFC的消息映射机制   MFC的设计者们在设计MFC时,紧紧把握一个目标,那就是尽可能使得MFC的代码要小,速度尽可能快。为了这个目标,他们使用了许多技巧,其中很多技巧体现在宏的运用上,实现MFC的消息映射的机制就是其中之一。
869 0
|
前端开发 vr&ar C++
进入MFC讲坛的前言(五)
框窗、视图和文档及其关系   MFC架构的另外一个特色是它的框窗、视图和文档这个三位一体的结构,它是一个典型的MVC(Model、View and Controler)结构。严格的讲,框窗不属于MVC中的任何一项,MFC设计者将框窗加进来是为了能更好的协调文档 和视图。
761 0