Win32 SDK相关常见面试题

1.      Win32应用程序的基本类型.

win32应用程序包含windows窗口程序和控制台程序2.

窗体程序内置模板代码,控制台程序适合编写dos程序

2.      创建win32窗口程序的几个步骤,及使用到的函数。

// 注册窗口类 
RegisterClass(&wc);
// 创建窗口 
    HWND hwnd = CreateWindow( 
        cls_Name,           //类名,要和刚才注册的一致 
        L"我的应用程序",  //窗口标题文字 
        WS_OVERLAPPEDWINDOW, //窗口外观样式 
        38,                 //窗口相对于父级的X坐标 
        20,                 //窗口相对于父级的Y坐标 
        480,                //窗口的宽度 
        250,                //窗口的高度 
        NULL,               //没有父窗口,为NULL 
        NULL,               //没有菜单,为NULL 
        hInstance,          //当前应用程序的实例句柄 
        NULL);              //没有附加数据,为NULL 
    if(hwnd == NULL) //检查窗口是否创建成功 
        return 0; 
 
    // 显示窗口 
    ShowWindow(hwnd, SW_SHOW); 
 
    // 更新窗口 
    UpdateWindow(hwnd); 
 
    // 消息循环 
    MSG msg; 
    while(GetMessage(&msg, NULL, 0,0)) 
    { 
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    } 
    return 0; 
} 


 4.      有哪些字符集? Win32对于各种字符集如何进行兼容及转换? (wchar_tTCHARTEXT() )

单子节字符集,多字节字符集,Unicode字符有时也被称作宽字符。

6.      窗口类的分类,如何创建一个应用程序全局窗口类。

window系统提供了三种类型的窗口类

· 系统全局类(System global classes

· 应用程序全局类(Application global classes

· 应用程序局部类(Application local classes

7.      Win32窗口程序运行机制与控制台程序的运行机制有何区别?

控制台程序:做DOS下使用的程序用的,或者是一个后台运行的服务程序,或者在某些终端使用,不需要用户界面的程序。

8.      Getmessage函数的作用,与Peekmessage函数的区别。

GetMessage在没有产生消息的时候并不返回,而是一直在等待,直到一个消息返回;当消息不是WM_QUIT时,返回一个非零值,也就是说,当是WM_QUIT时会返回一个零。

PeekMessage不管有没有消息都会返回一个值,有消息是非零值,没有消息则是零值。最后一个参数有PM_NOREMOVE和PM_REMOVE两种方式,前一种就是取完消息后不删除消息

9.      发送WM_QUIT消息使程序终止的内部过程。

win32应用程序的完整退出过程:点击窗口右上角的关闭按钮,发送WM_CLOSE消息。此消息处理中调用DestroyWindow函数,发送WM_DESTROY消息。此消息处理中调用PostQuitMessage(0)函数,发送WM_QUIT消息到消息队列中。GetMessage捕获到WM_QUIT,返回0,退出循环(应用程序真正退出)。

MFC应用程序的完整退出过程:点击窗口右上角的关闭按钮,或选择【File/Close】,发出 WM_CLOSE消息。CMyFrameWnd 并没有设置WM_CLOSE 处理常式,于是交给预设之处理常式。预设函数对于WM_CLOSE 的处理方式是呼叫 ::DestroyWindow, 并因而发出WM_DESTROY。预设之WM_DESTROY 处理方式是呼叫::PostQuitMessage,因此发出WM_QUIT。CWinApp::Run 收到WM_QUIT 后会结束其内部之讯息回路, 然后呼叫ExitInstance,这是CWinApp 的一个虚拟函数。如果自己应用程序类CMyWinApp 改写了ExitInstance , 那么CWinApp::Run 所呼叫的就是CMyWinApp::ExitInstance,否则就是 CWinApp::ExitInstance。最后回到 AfxWinMain,执行 AfxWinTerm,结束程序。

11. TranslateMessageDispatchMessage的作用。

DispatchMessage:派遣消息给相应的窗口过程。
TranslateMessage:转换虚拟键信息到字符消息。

12. SendMessagePostMessage的区别。

SendMessage:发送消息给指定的窗口过程;直到窗口过程处理了消息才返回。
PostMessage:将消息放入消息队列(与指定窗口创建的线程相关)中;无需等待消息处理,立即返回。不能发送WM_QUIT消息,此消息只能由PostQuitMessage函数发送。

13. Win32消息机制获取消息的过程(先查看什么消息?再查看什么消息?)

Windows把消息分为两种:一种是需要立即处理的消息,另一种是不需要立即处理的消息。

对于需要立即处理的消息,Windows直接把它送给窗口的消息处理函数进行处理,这类消息我们叫做非队列消息

而对于不需要立即处理的消息,Windows会把它发送给应用程序的消息队列进行排队,由应用程序逐个进行处理,我们把这类消息叫做队列消息

1Windows操作系统有一个消息队列,它存放操作系统收到的消息。如:当按键被按下,键盘会发送一个消息到操作系统的消息队列。

2、操作系统把系统消息队列中的消息分派到各个应用程序的消息队列。如果它是第1个应用程序的消息,操作系统把它发给第1个应用程序,把它放在第1个应用程序的消息队列;如果它是第2个应用程序的消息,发送给第2个程序的消息队列。

3、应用程序的消息循环从自己的消息队列中取消息,取出的消息调用窗口过程函数进行处理。

14. 知道有哪几类主要的消息。(WM_CREATE,WM_DESTROY, WM_SIZE, WM_SYSCOMMAND, WM_COMMAND,  WM_PAINT,  鼠标消息, 键盘消息)

16. 用户自定义消息如何定义。

case WM_COMMAND: //消息
  if(wParam == 菜单id)
  {
    postMessage(hWnd, WM_MSG, ID_USER, NULL); 发送自定义消息?
  }
  break;
case WM_MSG: //自定义消息


17. 创建菜单、设置菜单的函数,在哪处理菜单命令的消息。

在WindowProc里,设置WM_COMMAND消息

        case  WM_COMMAND
        {
                   switch(LOWORD(wparam))
{
case MENU_FILE_OPEN:
{

}
break;
case MENU_FILE_SAVEAS:
{
          }

MENU_FILE_OPEN, MENU_FILE_SAVEAS等为菜单项的ID


18. 加速键如何使用?

1. 取得程序的实例句柄(hInstance)

2. LoadMenu装入菜单,得到菜单句柄

3. LoadAccelerator装入加速键,得到加速键句柄

4. 注册窗口类

5. 创建窗口时在参数中制定菜单句柄

6. 显示窗口

7. 然后进入消息循环,在消息循环中用TranslateAccelerator来进行加速键的检测

 

19. GDI绘图对象,使用的步骤,及函数。

20. 使用位图的步骤及用到的主要函数。

21. 可用于文字绘制的API函数。

22. 有模式对话框与无模式对话框的区别,创建步骤。收到的创建消息是什么?

23. 子控件和父窗口通过什么进行通信? 父窗口在哪里处理子窗口发送的消息?

  子控件和父窗口(一般窗口或者对话框)的交互都是通过消息完成。如果子窗口状态发生变化,子窗口会向父窗口发送相应的消息。一般父窗口会使用SendMessage函数向子窗口发送消息。

    父窗口响应子窗口发送的消息一般是在WM_COMMAND进行处理。

24. 有哪些常见的子控件?(静态框、编辑框、按钮、listboxcomboBox、滚动条)

25. 什么样的控件支持自绘制?

按钮控件,列表框控件,组合框,

26. 动态库与静态库的区别。

27. Win32里面怎样用静态库? C++程序在引用c的静态库时,需要注意什么?

Dll包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library。

lib包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库static link library。

使用dll需注意三个文件
1).h头文件,包含dll中说明输出的类或符号原型或数据结构的.h文件。应用程序调用dll时,需要将该文件包含入应用程序的源文件中。
2).LIB文件,是dll在编译、链接成功之后生成的文件,作用是当其他应用程序调用dll时,需要将该文件引入应用程序,否则产生错误。如果不想用lib文件或者没有lib文件,可以用WIN32 API函数LoadLibrary、GetProcAddress装载。
3).dll文件,真正的可执行文件,开发成功后的应用程序在发布时,只需要有.exe文件和.dll文件,并不需要.lib文件和.h头文件。

使用lib需注意两个文件
1).h头文件,包含lib中说明输出的类或符号原型或数据结构。应用程序调用lib时,需要将该文件包含入应用程序的源文件中。
2).lib文件,见上面。

隐式链接:第一种方法是:通过project->link->Object/Library Module中加入.lib文件(或者在源代码中加入指令#pragma comment(lib, “Lib.lib”)),并将.dll文件置入工程所在目录,然后添加对应的.h头文件。

显式链接:需要函数指针和WIN32 API函数LoadLibraryGetProcAddress装载,使用这种载入方法,不需要.lib文件和.h头文件,只需要.dll文件即可.

Windows将遵循下面的搜索顺序来定位DLL:
1)包含EXE文件的目录
2)工程目录
3)Windows系统目录
4)Windows目录
5)列在Path环境变量中的一系列目录

28. Win32里面动态库有哪几种导出方式,有哪几种导入方式?(注意c++的导出方式)

导出动态库函数:

(1)使用__declspec(dllexport)方式,在函数前增加关键字,以C++方式导出

__declspec(dllexport)导出的函数由于函数名称发生变化,所以无法使用函数名称获取对应函数地址,所以尽量采用隐式链接的方式。

extern “C”__declspec(dllexport)方式导出的函数可以正常使用函数名称获取函数地址。

(2)增加extern “C”方式,以C语言方式导出

(3)使用def方式导出(在项目中添加*.def文件)

30. Windows地址空间的划分。

http://blog.csdn.net/dog250/article/details/16356141

31. Windows 内存使用的几种方式及相应的函数(虚拟内存、堆内存、栈内存)

32. Malloc内部调用A函数,A函数调用B函数。AB分别是什么?

 malloc_init   sbrk(0)

33. 内存映射文件的作用。主要函数。

Windows提供了3种进行内存管理的方法

• 虚拟内存,最适合用来管理大型对象结构数组 

• 内存映射文件,最适合用来管理大型数据流(通常来自文件)以及在单个计算机上运行的多个进程之间共享数据 

内存堆栈,最适合用来管理大量的小对象

int _tmain(int argc, _TCHAR* argv[])
{
   //Open the file that we want to map.
1) 创建或打开一个文件内核对象,该对象用于标识磁盘上你想用作内存映射文件的文件。
   //注意请在c盘,自己创建一个kuan.txt文件,并写入内容
  HANDLE hFile = ::CreateFile(L"C:\\kuan.txt",
     GENERIC_READ | GENERIC_WRITE,
     0,
     NULL,
     OPEN_ALWAYS,
     FILE_ATTRIBUTE_NORMAL,
     NULL);
   //Create a file-mapping object for the file.
2) 创建一个文件映射内核对象,告诉系统该文件的大小和你打算如何访问该文件。
  HANDLE hFileMapping = ::CreateFileMapping(hFile,
     NULL,
     PAGE_WRITECOPY,
     0, 0,
     NULL);
3) 让系统将文件映射对象的全部或一部分映射到你的进程地址空间中。
  PBYTE pbFile = (PBYTE)::MapViewOfFile(hFileMapping, FILE_MAP_COPY, 0, 0,0);
  cout << pbFile << endl;
当完成对内存映射文件的使用时,必须执行下面这些步骤将它清除:
1) 告诉系统从你的进程的地址空间中撤消文件映射内核对象的映像。
2) 关闭文件映射内核对象。
3) 关闭文件内核对象。
  ::UnmapViewOfFile(pbFile);
  ::CloseHandle(hFileMapping);
  ::CloseHandle(hFile);
    return 0;
}


34. 创建进程和打开进程用什么函数? 有什么区别?

ShellExecute   CreateProcess

http://blog.csdn.net/tcjiaan/article/details/8620731

http://www.cnblogs.com/xubin0523/archive/2012/11/01/2749729.html

35. 创建线程用什么函数?

36. WaitforsingleobjectWaitformultiobjects的区别。Waitforsingleobject的第二个参数为0表示什么意思?

如果传递了0WaitForSingleObject函数将总是立即返回。WaitForSingleObject的返回值能够指明调用线程为什么再次变为可调度状态。如果线程等待的对象变为已通知状态,那么返回值是WAIT_OBJECT_0。如果设置的超时已经到期,则返回值是WAIT_TIMEOUT。如果将一个错误的值(如一个无效句柄)传递给WaitForSingleObject,那么返回值将是WAIT_FAILED(若要了解详细信息,可调用GetLastError)。

37. 关闭线程和关闭进程的函数分别是什么?

TerminateProcess(pro_info.hProcess,exitCode); 

BOOL TerminateThread(HANDLE hThread,DWORDdwExitCode);

38. 线程局部存储(TLS)的意义,如何指定一个变量的TLS属性。

__declspec (thread)int iGlobal_1 = 1;

 

39. Win32线程同步提供的方式,及主要函数为什么?

Windows操作系统提供了多种同步手段,同步对象包括临界区(Critical Section)、事件(Event)、信号量(Semaphore)、互斥量(Mutex)等。

1      临界区对象(CRITICAL_SECTION),也称关键代码段   

 调用InitializeCriticalSection函数对它进行初始化,之后,线程访问临界区中数据的时候,必须首先调用 EnterCriticalSection 函数,申请进入临界, 当操作完成的时候,要调用LeaveCriticalSection函数将临界区交还给Windows系统,以便其他线程可以申请使用。

2      事件内核对象(event

要使用事件对象,首先用CreateEvent函数去创建它。

事件对象被建立后,程序可以通过SetEventResetEvent函数来设置它的状态。

事件内核对象的同步,代码上体现在对WaitForSingleObject/WaitForMultipleObjects函数的调用,等待事件对象的置信。

CloseHandle(g_hEvent);

3      信号量内核对象(Semaphore

首先使用CreateSemaphore函数创建信号量内核对象。

信号量内核对象的同步,代码上体现在对WaitForSingleObject/WaitForMultipleObjects函数的调用,其同步条件为资源计数大于0,即有可用资源。某个线程处理完共享资源后,需要调用ReleaseSemaphore释放资源,增加可用资源计数。当然,同其他内核对象一样,最终也得调用CloseHandle函数释放信号量内核对象占用的资源。

4      互斥内核对象(Mutex

基于互斥内核对象来保持线程同步用到的函数主要有CreateMutexOpenMutexReleaseMutex,其用法在代码布局上同信号量内核对象。

当目前对资源具有访问权限的线程不再需要访问此资源而要离开时,必须通过ReleaseMutex函数来释放其拥有的互斥对象。

基于互斥内核对象的同步在代码上体现在对WaitForSingleObject/WaitForMultipleObjects函数的调用,以等待互斥内核对象的通知,其同步条件为某一时刻只有一个线程拥有互斥对象。

 

40. 提供的同步措施中哪些是内核对象? 试比较互斥量和临界区。

      同步机制的比较

在同步技术中,临界区是最容易掌握的。它是一种简单的数据结构。同通过等待和释放内核态互斥对象实现同步的方式相比,临界区的速度明显胜出。但是临界区非内核对象,不能用在多进程间的线程同步,只能用于单个进程内部的线程同步。但是,对于普通的单进程程序,鉴于临界区使用旋转锁优先在用户模式同步的高效性,使用临界区不失为一种普遍的同步方案。

事件内核对象是一种基本的内核对象,被广泛使用于多进程、多线程同步通信。实际上,临界区RTL_CRITICAL_SECTION内部即使用了事件内核对象。

信号量机制在内核模式工作,适用于允许特定个数的线程执行某任务。

互斥对象与其他内核对象不同,互斥对象在操作系统中拥有特殊代码,并由操作系统来管理

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值