Windows滚动条

//这是我初次编写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.lParam;  //如果得到一个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,cyChar,cyClient,iVscrollPos;

      int i,y;

      TCHAR szBuffer[10];

      TEXTMETRIC tm;

 

      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);

 

           //   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 低字节用于客户区的垂直大小

                 break;

 

           case WM_VSCROLL: //滚动条消息

                 switch(LOWORD(wParam))//wParam的低字节指出了鼠标对滚动条进行的操作

                 {

                 case SB_LINEUP:

                      iVscrollPos-=1;

                      break;

                 case SB_LINEDOWN:

                      iVscrollPos+=1;

                      break;

                 case SB_PAGEUP:

                      iVscrollPos-=cyClient/cyChar;

                      break;

                 case SB_PAGEDOWN:

                      iVscrollPos+=cyClient/cyChar;

                      break;

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

                      iVscrollPos=HIWORD(wParam);    //高字节附加参数,此时指出位置变化为释放后的/按下滚动条

                      break;

                 default:

                      break;

                 }

                 iVscrollPos=max(0,min(iVscrollPos,NUMLINES-1));  //使滚动条为位置不至于超出范围

                 if(iVscrollPos !=GetScrollPos(hwnd,SB_VERT))  

                 {

                      SetScrollPos(hwnd,SB_VERT,iVscrollPos,TRUE);   //重新设置滚动条位置

                      InvalidateRect(hwnd,NULL,TRUE);  //是客户区无效

                 //   UpdateWindow(hwnd);

                 }

                 return 0;

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

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

                 for(i=0;i<NUMLINES;i++)

                 {

                       y=cyChar*(i-iVscrollPos);

                      //y=cyChar*i;

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

 

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

                     

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

 

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

 

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

                 }

           /*   GetClientRect(hwnd,&rect);  //通过这个函数可以获得变化后的窗口大小(我也不知道怎么实现的)

                 DrawText(

                   hdc,          // handle to DC

                   TEXT("Hello,Windows xp!"), // text to draw

                   -1,       // text length

                   &rect,    // formatting dimensions

                   DT_SINGLELINE|DT_CENTER|DT_VCENTER     // text-drawing options

                      );*/

                 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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值