Windows程序设计 sysmets

//这是我初次编写windows应用程序(窗口),按理说是按书本上的抄录下来的,呵呵

//下面我把代码详细解释一下

 

/**********************一些字符前缀解释****************************************************/

/*cs_:class(类风格选项)WM_:widows message(窗口消息)CW_:creat widows(绘制窗口)

DT_:draw text(绘制文本选项)

RECT:rectangle(巨型)instance:实例 h:handle(句柄,行为,把手) vertical:垂直

horizontal:水平的

*/

 

//此程序中在窗口中添加了滚动条内容

#include <windows.h>

#include "SYSMETS.h"

 

LRESULT CALLBACK WndProc(

  HWND hwnd,              // handle to window

  UINT Msg,               // message

  WPARAM wParam,          // first message parameter

  LPARAM lParam           // second message parameter

);

 

int WINAPI WinMain(

  HINSTANCE hInstance,      // handle to current instance

  HINSTANCE hPrevInstance,  // handle to previous instance

  LPSTR lpCmdLine,          // command line

  int iCmdShow              // show state

)

{

      static TCHAR szAppName[]=TEXT("SysMets");

      MSG msg;               //定义一个消息结构

      WNDCLASS wndclass;

      //下面的一部分相当于设计,先初始化了窗口类的共有属性

      wndclass.style=CS_HREDRAW |CS_VREDRAW; //

      wndclass.lpfnWndProc=WndProc;   //指向所有基于这个类来创建的窗口所使用的窗口过程的地址

      wndclass.cbClsExtra=0;

      wndclass.cbWndExtra=0;

      wndclass.hInstance=hInstance;

      wndclass.hIcon=LoadIcon(NULL,IDI_ERROR);  //窗口左上角是一个叉的图标

      wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);  //光标选项(也就是鼠标)

      wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);  //客户区背景

      wndclass.lpszMenuName=NULL;  //vc中,有菜单,这个程序,没有菜单,所以为NULL

      wndclass.lpszClassName=szAppName;   //这个类的名字

 

      if(!RegisterClass(&wndclass))   //注册窗口类

      {

           MessageBox(NULL,TEXT("This program requires Windows NT!"),

                 szAppName,MB_ICONERROR);

           return 0;

      }

 

      HWND hwnd;  //定义一个窗口句柄,开始创建窗口

      hwnd=CreateWindow(                     //创建窗口

        szAppName,  // registered class name

        TEXT("The Hello Program"), // window name

      /*********************WS_OVERLAPPEDWINDOW 重叠式窗口****************************************************/

        //创建一个具有WS_OVERLAPPED,WS_CAPTION,WS_SYSMENU,WS_THICKFRAME,WS_MINIMIZEBOXWS_MAXIMIZEBOX

        /*WS_OVERLAPPEDWINDOW*/WS_MINIMIZEBOX|WS_OVERLAPPED|WS_SYSMENU|WS_THICKFRAME|WS_MAXIMIZEBOX|WS_VSCROLL|WS_HSCROLL,//增加垂直滚动条和水平滚动条  

        CW_USEDEFAULT,                // horizontal position of window

        CW_USEDEFAULT,                // vertical position of window

        CW_USEDEFAULT,           // window width

        CW_USEDEFAULT,          // window height

        NULL,      // handle to parent or owner window

        NULL,          // menu handle or child identifier

        hInstance,  // handle to application instance

        NULL       // window-creation data

      );

 

      ShowWindow(hwnd,iCmdShow);    //显示窗口

      UpdateWindow(hwnd);           //更新窗口

      while(GetMessage(&msg,NULL,0,0)) //消息循环(这一步是从消息队列中得到消息)  

      {

           TranslateMessage(&msg);  //消息转换

           DispatchMessage(&msg);  //消息映射(如果在MFC中,这是一个非常难的难点)

      }

      return msg.wParam;  //如果得到一个WM_QUIT消息,退出while()循环,程序返回结束

}

 

//窗口过程函数

LRESULT CALLBACK WndProc(   

  HWND hwnd,              // handle to window

  UINT msg,               // message

  WPARAM wParam,          // first message parameter

  LPARAM lParam           // second message parameter

)

{

      static int cxChar,cxCaps,cxClient,cyChar,cyClient,iMaxWidth;

      int i,x,y,iPaintBeg,iPaintEnd,iVertPos,iHorzPos;

      TCHAR szBuffer[10];

      TEXTMETRIC tm;

 

      SCROLLINFO si;

      HDC hdc;

      PAINTSTRUCT ps;

//   RECT rect;

      switch(msg)

      {

 

           case WM_CREATE:  //创建窗口时由windows发送给窗口过程的,此时消息并没有进入消息队列

                 //   PlaySound(TEXT("hello,war"),NULL,SND_FILENAME|SND_ASYNC);

 

                 hdc=GetDC(hwnd);

 

                 GetTextMetrics(hdc,&tm);   //用来确定字体的大小

                 cxChar=tm.tmAveCharWidth;

                 cxCaps=(tm.tmPitchAndFamily&1 ? 3 :2)*cxChar/2;

                 cyChar=tm.tmHeight+tm.tmExternalLeading;

                 ReleaseDC(hwnd,hdc);

 

                 iMaxWidth=40*cxChar +22*cxCaps;//设置水平位置最大值(可是为啥一个*40,一个*22呢?)

 

           //   SetScrollRange(hwnd,SB_VERT,0,NUMLINES-1,FALSE);   //设置垂直滚动条的范围(自我感觉一下两句没有用处)

           //   SetScrollPos(hwnd,SB_VERT,iVscrollPos,TRUE);   //设置垂直滚动条的位置

                 return 0;

 

      case WM_SIZE:  //窗口大小改变时,产生的消息(当然,窗口第一次显示时,也是要产生这个消息的,接下来必然跟着WM_PAINT消息)

                 cyClient=HIWORD(lParam);  //lParam 高字节用于客户区的垂直大小

                 cxClient=LOWORD(lParam);  // lparam 低字节用于客户区的水平大小

 

                 si.cbSize=sizeof(si);

                 si.fMask=SIF_RANGE|SIF_PAGE; //设置范围和页面

                 si.nMin=0;

                 si.nMax=NUMLINES-1;

                 si.nPage=cyClient/cyChar;

                 SetScrollInfo(hwnd,SB_VERT,&si,TRUE); //设置垂直结构

 

           /*   si.cbSize=sizeof(si);

                 si.fMask=SIF_RANGE|SIF_PAGE; //设置范围和页面

                 si.nMin=0;

                 si.nMax=2+iMaxWidth/cxChar; //设置水平位置最大值,用到了上面的iMaxWidth

                 si.nPage=cxClient/cxChar;

                 SetScrollInfo(hwnd,SB_HORZ,&si,TRUE); //设置水平结构*/

                

                 return 0; 

 

           case WM_VSCROLL: //垂直滚动条消息

                 si.cbSize=sizeof(si);

                 si.fMask=SIF_ALL;

                 GetScrollInfo(hwnd,SB_VERT,&si);

                 iVertPos=si.nPos;

                 switch(LOWORD(wParam))//wParam的低字节指出了鼠标对滚动条进行的操作,高字节是附加参数(SB_THUMBTRACKSB_THUMBPOSITION对应着)

                 {

                 case SB_TOP:

                      si.nPos=si.nMin;

                      break;

                 case SB_BOTTOM:

                      si.nPos=si.nMax;

                      break;

                 case SB_LINEUP:

                      si.nPos-=1;

                      break;

                 case SB_LINEDOWN:

                      si.nPos+=1;

                      break;

                 case SB_PAGEUP:

                      si.nPos-=si.nPage;

                      break;

                 case SB_PAGEDOWN:

                      si.nPos+=si.nPage;

                      break;

                 case SB_THUMBTRACK:   //释放滚动条/按下滚动条

                      si.nPos=si.nTrackPos;    //高字节附加参数,此时指出位置变化为释放后的/按下滚动条

                      break;

                 default:

                      break;

                 }

 

                 si.fMask=SIF_POS;

                 SetScrollInfo(hwnd,SB_VERT,&si,TRUE);

                 GetScrollInfo(hwnd,SB_VERT,&si);

 

                 if(si.nPos !=iVertPos) 

                 {

                     

                      ScrollWindow(hwnd,0,cyChar*(iVertPos-si.nPos),NULL,NULL);

                      UpdateWindow(hwnd);

                 }

                 return 0;

 

           case WM_HSCROLL: //水平滚动条消息

                 si.cbSize=sizeof(si);

                 si.fMask=SIF_ALL;

                 GetScrollInfo(hwnd,SB_HORZ,&si);

                 iHorzPos=si.nPos;

                 switch(LOWORD(wParam))//wParam的低字节指出了鼠标对滚动条进行的操作,高字节是附加参数(SB_THUMBTRACKSB_THUMBPOSITION对应着)

                 {

                

                 case SB_LINERIGHT:

                      si.nPos+=1;

                      break;

                 case SB_LINELEFT:

                      si.nPos-=1;

                      break;

                 case SB_PAGELEFT:    //不知道咋回事的,这个消息(和下一个消息)一直响应不了,也不知道为啥

                      si.nPos-=si.nPage;

                      break;

                 case SB_PAGERIGHT:

                      si.nPos+=si.nPage;

                      break;

                 case SB_THUMBTRACK:   //释放滚动条/按下滚动条

                      si.nPos=si.nTrackPos;    //高字节附加参数,此时指出位置变化为释放后的/按下滚动条

                      break;

                 default:

                      break;

                 }

 

                 si.fMask=SIF_POS;

                 SetScrollInfo(hwnd,SB_HORZ,&si,TRUE);

                 GetScrollInfo(hwnd,SB_HORZ,&si);

 

                 if(si.nPos !=iHorzPos) 

                 {   

                      ScrollWindow(hwnd,cxChar*(iHorzPos-si.nPos),0,NULL,NULL);

                      UpdateWindow(hwnd);

                 }

                 return 0;

           case WM_PAINT: //此消息也不是从消息队列中获得的,也是widows发送的

                 hdc=BeginPaint(hwnd,&ps);  //返回的是一个"设备描述表句柄"

 

                 si.cbSize=sizeof(si);

                 si.fMask=SIF_POS;

                 GetScrollInfo(hwnd,SB_VERT,&si);

                 iVertPos=si.nPos;

 

                 GetScrollInfo(hwnd,SB_HORZ,&si);

                 iHorzPos=si.nPos;

          

                 iPaintBeg=max(0,iVertPos+ps.rcPaint.top/cyChar);

                 iPaintEnd=min(NUMLINES-1,iVertPos+ps.rcPaint.bottom/cyChar);

 

                 for(i=iPaintBeg;i<=iPaintEnd;i++)

                 {

                      x=cxChar *(1-iHorzPos);

                      y=cyChar*(i-iVertPos);

                     

                      TextOut(hdc,x,y,sysmetrics[i].szLabel,lstrlen(sysmetrics[i].szLabel));  //显示第一列

 

                      TextOut(hdc,x+32*cxCaps,y,sysmetrics[i].szDesc,lstrlen(sysmetrics[i].szLabel));   //显示第一列

                     

                      SetTextAlign(hdc,TA_RIGHT|TA_TOP); //设置为对齐方式(右上对齐)

 

                       TextOut(hdc,x+22*cxCaps+150*cxChar,y,szBuffer,wsprintf(szBuffer,TEXT("%5d"),GetSystemMetrics(sysmetrics[i].ilndex)));//显示第三列

 

                      SetTextAlign(hdc,TA_LEFT|TA_TOP);  //设置为对齐方式(重新设置为普通方式对齐)

                 }

                 EndPaint(hwnd,&ps);

                 return 0;

           case WM_DESTROY:

                 PostQuitMessage(0);

                 return 0;

      }

      return DefWindowProc(hwnd,msg,wParam,lParam);

}

/*分析WM_PAINT消息:如果用户最终单击了关闭按钮,DefWindowProc处理键盘和鼠标输入,检测到close选项后,

给窗口过程发送一个WM_SYSCOMMAND消息,WndProc将这个消息传给DefWindowProc,此函数给窗口过程发送一个WM_CLOSE消息

来响应之,DestroyWindow 导致Windows给窗口过程发送一个WM_DESTROY消息。WndProc再调用PostQuitMessage,将一个

 

WM_QUIT

消息放入消息队列中,以此来响应此消息,这个消息导致WinMain中的消息循环终止,循环结束。*/

 

//消息分为进队消息和不进队消息,从上面可以看出,在窗口没有创建以前,WM_CREATEWM_PAINT

//都是不进队列的,直接由windows发送,不管我们的事

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值