• Windows程序设计1(工具、编码、窗口)


     

    一、几个常用小工具:

    1. 编译器:CL.EXE   将源文件转变为目标文件(汇编语言)

      CL.EXE  /c  xxx.c  或   xx.cpp  

      cl.exe  -? 显示cl帮助

      cl.exe  /c  只编译不链接

      cl.exe  /Tc  编译c文件

      cl.exe  /l   头文件路径

     链接器:LINK.EXE  将目标文件转变为二进制文件(机器语言)

           LINK.EXE  xxx.obj  user32.lib  xxx.lib等需要的相关库文件(link.exe   ***.obj  ***.lib

     资源编译器:RC.EXE   将资源(**.rc)编译(**.res),最终通过链接器存入最终文件(.rc资源脚本文件)

     执行: ***.exe

    2设置控制台的输出代码页:

      BOOL SetConsoleOutputCP(UINT  wCodePageID);//代码页ID936中文,437英文。

      若不设置,ascII 将后面128个无法正常显示,正常显示前128个。

      编码方式:四种:ASC码、ASCII码,DBCS码、UNICODE

      wchar_t 宽字节字符,每个字符占两个字节,实际上是unsigned short 类型,定义时候需要在前面加:”L”,告知编译器按照双字节编译字符串.采用UNICODE编码,char占用一个字节。

      如wchar_t  *pwszText=L”hello wchar_t !”;

      wpritf(L”%s ”,pwszText) ;

      ///不可用printf,求字节长度:wcslen(pwszText);不可用strlen();

      另外使用时,定义: #define  UNICODE 应放在尽量的在最前面,防止在其他头文件不起作用。

      wprintf()UNICODE支持不是很完善,可通过下面更好的控制台输出

      BOOL WriteConsole(

        HANDLE  hConsoleOutput, //标准输出句柄

          CONST VOID   *lpBuffer,  // 输出内容的buffer

        DWORD    nNumberOfCharsToWrite, // 输出内容的长度

        LPDWORD    lpNumberOfCharsWritten, // 返回实际输出的内容长度

          LPVOID    lpReserved      // 备用

      );

      操作系统已经预备了三个句柄:标准输出句柄、标准输入句柄、标准错误句柄。GetStdHandle()可返回获取这三种句柄。

     

    二、NMAKEMakefile

      1. nmake为一个解释执行的工具,根据makefile文件的定义,编译和链接程序,最终生成目标文件。

      2. makefile定义编译和链接等操作的脚本文件(把项目的处理命令写入)(**.mak为后缀的文件),一般对整个向项目进行处理。

      Makefile语法:

        HELLO:依赖行     ////可以有多个依赖行

        //依赖行如下3

        cl.exe  /c  hello.c      ///命令行

        rc.exe hello.rc     ///命令行

        link.exe  hello.obj  hello.res  user32.lib     ///命令行

      其执行方式:

        1.首先找到第一个依赖行。

        2.检查依赖行的依赖项,若发现依赖项,则先执行依赖项的命令行。

        3.执行完所有的依赖项命令后,再执行自己的命令行。

        A:B

        5**.**  **

        6**.**  **

        B:C

        3**.**  **

        4**.**  **

        C:

        1**.**  **

        2**.**  **

      则执行顺序:C->B->A。也即:(1->2->3......->6)

      如:(HELLOCLEAN是标识而已,一般大写)

      HELLO:

          cl.exe  /c  my.cpp

          rc.exe  my.rc

          link.exe  my.obj  my.res  user32.lib

      CLEAN:

          del *.obj

          del *.res

      执行:nmake  /f  **.mak  CLEAN

      若果没有加/f CLEAN ,则只会执行HELLO的。

      改进:

        CLEAN:HELLO

           del *.obj

           del *.res

        HELLO:

           cl.exe  /c  my.cpp

           rc.exe  my.rc

           link.exe  my.obj  my.res  user32.lib

      ///先执行CLEAN,发现依赖项HELLO,在执行HELLO的依赖项目。

      ///最后CLEAN再执行自己的依赖项目

    三、Windows下的库与头文件

      库: kernel32.dll 提供核心的API:线程、进程、内存管理等。

         user32.dll  提供了窗口、消息等API

         gdi32.dll  绘图相关的API

      头文件:windows.h    所有windows头文件的集合(使用时包含此头文件,即可包含以下头文件,winnt.h)。

        windef.h windows数据类型。

        winbase.h kernel32API

        wingdi.h gdi32API

        winuser.h user32API

        winnt.h UNICODE字符集支持。

    四、Windows程序设计基础

      (HINSTANCE)句柄:用来找到内存,但是句柄绝对不是指针。

      入口函数:

      int  WINAPI  WinMain(

        HINSTANCE  hInstance,//当前程序的实例句柄

        HINSTANCE  hPrevInstance,//当前程序前一个实例句柄。现在为无用的参数。兼容而已。

        LPSTR  lpCmdLine,//命令行参数字符串

        int  nCmdShow,//窗口显示方式。

      );

      消息框:

      int  MessageBox

        HWND  hWnd,//父窗口句柄

        LPCTSTR  lpText,//显示消息框中的文字

        LPCTSTR  lpCaption,//显示在消息框标题栏上的文字

        UINT     uType///消息框中图标按钮类型风格

      );///返回点击的按钮的ID

      窗口程序的编写步骤:

        1 定义WinMain()入口函数

        2 定义窗口处理函数WindowProc()(处理消息)

        3 注册窗口类WNDCLASS wndclassRegisterClass(&wndclass),注册到操作系统

        4 创建窗口CreateWindow()(只是创建到内存的数据,并没绘制)

        5 显示窗口ShowWindow() / UpdateWindow()

        6 消息循环(GetMessage()提取消息、TranslateMessage()翻译消息、DispatchMessage()派发消息)

        7 消息处理

      窗口类包含了窗口的各种参数信息的数据结构。每个窗口都具有窗口类,基于窗口类创建窗口。每个窗口类都具有一个名称,使用前必须注册到系统。

      窗口类分为三类:系统窗口类、应用程序全局窗口类、应用程序局部窗口类。

      特点分别为:系统已经定义好的窗口类,所有应用程序都可以直接使用,不需要注册,如:按钮  BUTTON,编辑框 EDIT,它们的类名就是BUTTONEDIT等。由用户自己定义,当前应用程序所有子进程

      模块都可以使用它,注册窗口类型在窗口类风格中增加:wndclass.style=CS_GLOBALCLASS|**|**,也会使得程序的开发、使用维护,错误检测变得困难。

      由用户自己定义,当前应用程序中本进程模块可以使用它,不加风格CS_GLOBALCLASS

      窗口类的查找过程:

        1.系统根据传入的窗口类名称,在应用程序局部窗口类中查找,若找到执行2.否则执行3

        2.比较局部窗口类与创建窗口时传入的HINSTANCE变量,如发现相等,创建和注册的窗口类在同一模块(进程),创建窗口返回。否则继续执行3

        3.在应用程序全局窗口类,(此时不用再匹配HINSTANCE变量了)若找到执行4.否则执行5

        4.使用找到的窗口类的信息,创建窗口并返回。

        5.在系统窗口类中查找,若找到创建窗口返回,否则创建窗口失败。

        (因此,在创建窗口时,速度上:创建局部窗口>创建全局窗口>创建系统窗口)

      子窗口的创建:

        1.创建时要设置父窗口的句柄。

          2.创建风格要增加WS_CHILD|WS_VISIBLE

      窗口类的风格:

        CS_GLOBALCLASS - 应用程序全局窗口类

        CS_BYTEALIGNCLIENT - 窗口客户区的水平位置8倍数对齐

        CS_BYTEALIGNWINDOW - 窗口的水平位置8倍数对齐

        CS_HREDRAW - 当窗口水平变化时,窗口重新绘制

        CS_VREDRAW - 当窗口垂直变化时,窗口重新绘制

        CS_CLASSDC - 该类型的窗口,都是有同一个绘图(DC)设备

        CS_PARENTDC - 该类型的窗口,使用它的父窗口的绘图(DC)设备

        CS_OWNDC - 该类型的窗口,每个窗口都使用自己的绘图(DC)设备

        CS_SAVEBITS - 允许窗口保存成图(位图),提高窗口的绘图效率,但是耗费内存资源

        CS_DBLCLKS - 允许窗口接收鼠标左键双击

        CS_NOCLOSE - 窗口没有关闭按钮

      GetClassInfo / GetClassInfoEx 获取窗口类信息。

      ShowWindow(hWnd ,…)

      {

    1. 根据hWnd,找到窗口信息的那块内存。
    2. 再根据内存储存的关于窗口的各项信息,绘制窗口。

      }

    五、第一个Win 32 程序

    #include <windows.h>

    LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam , LPARAM lParam)//处理消息函数

    {

      return DefWindowProc(hWnd,uMsg,wParam,lParam); //自动处理许多消息

    }

    int WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine,  int  nCmdShow)

    {

      static TCHAR szAppName[]=TEXT("WINNT"); //TEXT为宏,非函数

      HWND hWnd;// 创建窗口句柄

      MSG msg;//消息结构体

      WNDCLASS wndclass;

          wndclass.style=CS_HREDRAW|CS_VREDRAW;// 窗口类风格,水平或垂直移动刷新窗口,

          wndclass.lpfnWndProc=(WNDPROC)WndProc; //回调函数指针

          wndclass.cbClsExtra=0; //窗口类附加数据大小

          wndclass.cbWndExtra=0; //窗口附加数据大小

          wndclass.hInstance=hInstance; //当前模块的实例句柄

          wndclass.hIcon=NULL; //窗口图标句柄

          wndclass.hCursor=NULL; //鼠标光标句柄

          wndclass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1); //窗口背景画刷

          wndclass.lpszMenuName=NULL; //窗口菜单的资源ID字符串

          wndclass.lpszClassName=szAppName;//窗口类的名称

      RegisterClass(&wndclass);//将所有信息注册到操作系统

    ///卸载:UnregisterClass(szAppName, hInstance);

      hWnd=CreateWindow(

          szAppName,//注册的窗口类名

          TEXT("第一个win32程序!"),//窗口标签

          WS_OVERLAPPEDWINDOW,//窗口风格具有水平与垂直滚动条

          100,//x的起点

          100,//y的起点

          500,//窗口的高度

          500,//窗口的宽度

          NULL,//父窗口句柄

          NULL,//菜单或子窗口句柄

          hInstance,//应用程序实例句柄

          NULL///附加数据

      );

      ShowWindow(hWnd,SW_SHOW); //创建成功则显示窗口

      UpdateWindow(hWnd); ///送出WM_PAINT消息

      while(GetMessage(&msg,NULL,0,0))//消息循环,获取消息

      {

         TranslateMessage (&msg); //检索消息,转化消息

         DispatchMessage (&msg); //将消息间接传给函数指针,传回给窗口函数(回调函数)

      }

      return msg.wParam; ///PostQuitMessage返回的值.PostQuitMessage(0)结束消息循环

    }

    六、窗口类的使用

      定义数据空间的大小(WNDCLASSEX结构体中)int  cbClsExtra;   //一般定义为4字节的倍数(0,4,8,….)(若为100,则索引号只能最多为96,若200,则196,由于新值为long,至索引号后剩下的要留足4个字节空间)

      重存入数据:

      DWORD SetClassLong(

        HWND   hWnd, //窗口句柄,

        int    nIndex, //字节索引号,也取4字节地整数倍

        LONG dwNewLong  //////新的数据值。指针变量也可以

        );//返回原数据值

      读取数据:

      DWORD GetClassLong(

        HWND   hWnd, ///窗口句柄

        int    nIndex ////字节索引号

        );//返回获取值

    七、窗口使用

      定义数据空间大小:int cbWndExtra;///同样一般定义为4字节的整数倍;

      重存入数据:

      LONG   SetWindowLong(

        HWND hWnd,    ///窗口句柄

        int nIndex, ///设置补偿值

        LONG dwNewLong  //////新的数据值

      );//返回先前的数据值

      读取数据:

      LONG GetWindowLong(

           HWND hWnd,   //窗口句柄

           int nIndex   //取回补偿值

      );

      窗口类附加数据与窗口附加数据区别:

      前者的附加数据提供的BUFF,是所有该类窗口共享的BUFF,后者的附加数据提供的BUFF,值属于该窗口所拥有,是窗口私有的BUFF

    八、MDI (多文档)窗口创建

    • 1 创建主窗口

         没有父窗口,需要注册窗口类。

        -在主窗口的窗口处理函数中,调用MDI主窗口的缺省处理函数DefFrameProc,不调用DefWindowProc函数。

    • 2 创建“MDICLIENT”窗口

        -父窗口是主窗口,窗口类为MDICLIENT

        -创建时,要使用创建参数CLIENTCREATESTRUCT 定义子窗口的起始ID

    • 3 创建子窗口

        -子窗口的父窗口是MDICLIENT”窗口,需要注册窗口类。

        -子窗口的窗口处理函数缺省调用DefMDIChildProc

  • 相关阅读:
    java 找不到或无法加载主类
    navicat connect error: Authentication plugin 'caching_sha2_password' cannot be loaded
    mysql command
    the diffirent between step into and step over (java)
    20181015
    Eclipse
    游戏2048源代码
    vue的生命周期
    简单快速了解Vue.js的开发流程
    C# 连接西门子PLC
  • 原文地址:https://www.cnblogs.com/haomiao/p/6747204.html
Copyright © 2020-2023  润新知