VC API常用函数简单例子大全十二(下)

第一百一十六个SetViewportOrgEx将窗口原点(0,0)映射到设备坐标点X,Y

函数定义:BOOL SetWindowOrgEx(HDC hdc, int X, int Y, LPPOINT lpPoint);

hdc是要映射的设备上下文,X,Y是要映射的坐标,lpPoint是窗口原点原来所映射的坐标,不需获取可为NULL。

比如这样一个语句:(假设hdc的设备模式为MM_TEXT)那么调用下面语句后

SetViewportOrgEx(hdc,200,200,NULL);

窗口的坐标就变成下面这样了:

看例子:

#include<windows.h>
int main()
{
HWND wnd=FindWindow(NULL,"无标题.txt - 记事本");
HDC hdc=GetDC(wnd);
::SetViewportOrgEx(hdc,200,200,NULL);//设置坐标点200,200为窗口原坐标点0,0
while(1)
{
 Rectangle(hdc,0,0,100,100);
 Rectangle(hdc,0,0,-100,-100);
 Sleep(300);
}
return 0;
}

第一百一十七个SetWindowOrgEx将设备坐标点X,Y映射到窗口原点0,0

函数定义:BOOL SetWindowOrgEx(HDC hdc, int X, int Y, LPPOINT lpPoint);

跟SetViewportOrgEx的映射正好相反,这个函数的参数解释参照SetViewportOrgEx。

这里仅给出调用

SetWidnowOrgEx(hdc,200,200,NULL);语句后的窗口坐标图。当然参数也可以为负数,可自行推算窗口坐标点。


第一百一十八个SetScrollPos设置滚动条位置

函数定义:int
SetScrollPos(
    HWND hWnd,//滚动条所在窗口句柄
    int nBar,//滚动条类型,参照SetScrollInfo函数
    int nPos,//滚动条位置
    BOOL bRedraw);//是否重画滚动条

例子:参考SetScrollInfo函数的例子。

第一百一十九个SetScrollInfo设置滚动条信息

函数定义:int SetScrollInfo(HWND hWnd;//滚动条所在的窗口句柄

int fnBar,//滚动条类型,SB_VERT垂直滚动条,SB_HORZ水平滚动条

LPSCROLLINFO lpsi,//滚动条各项信息结构体,后面会有介绍

BOOL fRedraw);//指明是否重画滚动条

SetScrollInfo函数的第三个参数是一个SCROLLINFO结构体指针,关于该结构体的解释如下:

typedef struct tagSCROLLINFO
{
    UINT    cbSize;//指明SCROLLINFO结构体大小,赋值sizeof(SCROLLINFO)
    UINT    fMask;//指明nMin-nMax、nPage、nPos哪些成员有效,分别对应SIF_RANGE、SIF_PAGE、SIF_POS。

     //为SIF_DISABLENOSCROLL表明禁用滚动条。
    int     nMin;//滚动条范围最小值
    int     nMax;//滚动条范围最大值
    UINT    nPage;//页大小(跟滚动条大小相关联)
    int     nPos;//滚动条位置
    int     nTrackPos;//这个成员在GetScrollInfo函数中有用。用于接收滚动条位置
}   SCROLLINFO, FAR *LPSCROLLINFO;

这里要说明的是,为了避免不必要的麻烦,滚动条大小,滚动条范围必须和可见窗口以及实际窗口(视图?)大小一致。

也就是说当你可见窗口大小是300的时候,那么滚动条页大小也必须是300。如果实际窗口大小是2000的时候,那么滚动条范围就是0~1999,分别是最小值和最大值。而滚动条可移动范围也就是位置是在0~1700,因为当滚动条位置是0的时候,显示窗口是0-300,而位置是1700的时候刚好显示完窗口也就是1700~2000。滚动条位置是以滚动条上边为准。

要想让一个窗口具有滚动条风格,在调用CreateWindow函数时在第三个参数里指明就行了,在CreateWindow函数里也解释过,WS_VSCROLL指明窗口具有垂直滚动条风格,而WS_HSCROLL是水平滚动条。

关于滚动条消息的解释(WM_VSCROLL垂直,WM_HSCROLL水平)

下面的消息码存存于wParam参数里:

SB_LINEUP 滚动条上面的箭头按钮被单击了一下,水平滚动条对应的是左边的按钮

SB_LINEDOWN 滚动条下面的箭头按钮被单击了下,水平滚动条对应的是右边的按钮

SB_PAGEUP 滚动条滑柄与上面箭头按钮之间的区域被单击了一下,水平滚动条是左边之间

SB_PAGEDOWN 滚动条滑柄与下面箭头按钮之间的区域被单击了一下,水平滚动条是右边之间。

SB_ENDSCROLL   鼠标离开了滚动条。

SB_THUMBTRACK  滚动条滑柄被拉动

SB_THUMBPOSITION  滚动条滑柄被拉完后,鼠标左键抬起时。

例子:垂直滚动条窗口应用

水平滚动条的使用方法,跟这个大同小异,所以就不加放进来了,徒增负担,这里面使用了一个最关键的函数SetWindowOrgEx,映射窗口原点,时时根据滚动条位置设置对应的窗口原点。以保证当前显示窗口正确的部分。每次有滚动信息产生的时候,都重画了窗口,这个方法很原始。以后讲到ScrollWIndow函数时会有改进的,还有本例部分参考了

Programing Windows with MFC里面的内容,只不过那里面是用类来实现的,而我这个是完全是用API来实现的,包括创建窗口,消息处理。

好吧,新建一个WIN32 工程,下面是代码:

#include<windows.h>
#include<stdio.h>
#define LINESIZE 8
int nVScrollPos=0,nVPageSize,nViewHeight=2000;
LRESULT CALLBACK WinSunProc(HWND wnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
       LPSTR lpCmdLine,int nCmdShow)
{
 WNDCLASS wndcls;
 wndcls.cbClsExtra=0;
 wndcls.cbWndExtra=0;
 wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
 wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);
 wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);
 wndcls.hInstance=hInstance;
 wndcls.lpfnWndProc=WinSunProc;
 wndcls.lpszClassName="windowclass";
 wndcls.lpszMenuName=NULL;
 wndcls.style=CS_HREDRAW|CS_VREDRAW;
 RegisterClass(&wndcls);
 HWND wnd;
 wnd=CreateWindow("windowclass","first windows",
  WS_OVERLAPPEDWINDOW^WS_SIZEBOX^WS_MAXIMIZEBOX|WS_VSCROLL,300,200,600,400,
  NULL,NULL,hInstance,NULL);
 RECT rect;
 GetClientRect(wnd,&rect);
 nVPageSize=rect.bottom;//可见窗口高度
    SCROLLINFO si;
 si.cbSize=sizeof(SCROLLINFO);
 si.nMin=0;
 si.nMax=1999;//窗口实际大小是2000
 si.nPage=nVPageSize;//可见窗口高度和页大小设置一致
    si.nPos=0;
 si.fMask=SIF_ALL;
 ::SetScrollInfo(wnd,SB_VERT,&si,FALSE);//设置滚动条信息
 ShowWindow(wnd,SW_SHOWNORMAL);
 UpdateWindow(wnd);
 MSG msg;
 while(GetMessage(&msg,NULL,0,0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
 return 0;
};
LRESULT CALLBACK WinSunProc(HWND wnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
 
  char str[20];
  PAINTSTRUCT ps;
  HDC hdc;
  int y,nDelta;
  int nScrollPos,nMaxPos;
switch(uMsg)
 {
  
 case WM_VSCROLL:
  {
   switch(LOWORD(wParam))//wParam的低二字节存储有滚动条消息码。
   {
   case SB_LINEUP:
    nDelta=-LINESIZE;//负数是向上滚动 LINESIZE 是滚动大小8
    break;
   case SB_PAGEUP:
    nDelta=-nVPageSize;//滚动一页,也就是可见窗口高度
    break;
   case SB_THUMBTRACK:
    //wParam的高二字节储存有滚动条的位置
    nDelta=(short int)HIWORD(wParam)-nVScrollPos;
    break;
   case SB_PAGEDOWN:
    nDelta=nVPageSize;
    break;
   case SB_LINEDOWN:
    nDelta=LINESIZE;
    break;
   default:
    return 0;
   }
  }
  //计算新位置
  //有这样一种情况,当滚动位置是5时,再向上滚动8个点,那是不可能的,所以要计算。
       nScrollPos=nVScrollPos+nDelta;
    nMaxPos=nViewHeight-nVPageSize;
   if(nScrollPos<0)
    nDelta=-nVScrollPos;
   else if(nScrollPos>nMaxPos)
    nDelta=nMaxPos-nVScrollPos;
   if(nDelta!=0)
   {
    nVScrollPos+=nDelta;
    SetScrollPos(wnd,SB_VERT,nVScrollPos,TRUE);//设置新位置
    ::InvalidateRect(wnd,NULL,TRUE);//刷新窗口
   }
 return 0;
 case WM_PAINT:
    hdc=BeginPaint(wnd,&ps);
    ::SetWindowOrgEx(hdc,0,nVScrollPos,NULL);
    for(y=0;y<2000;y+=20)
    {
     MoveToEx(hdc,0,y,NULL);
     LineTo(hdc,600,y);
     sprintf(str,"%d:",y);
     TextOut(hdc,0,y+2,str,strlen(str));
    }
  return 0;
 case WM_CLOSE: ::DestroyWindow(wnd);return 0;
    case WM_DESTROY:  PostQuitMessage(0);return 0;
 }

  return DefWindowProc(wnd,uMsg,wParam,lParam);

运行效果:

  • 20
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bczheng1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值