C#中用鼠标移动页面功能的实现(代码控制滚动条)
项目中需要实现以下功能:
打印预览控件中,可以用鼠标拖动页面,以查看超出显示范围之外的部分内容。
该功能本来可以通过拉动水平和垂直滚动条来实现,但实际使用中,用户更趋向于直接用鼠标拖动页面来实现,很多看图类软件都有这种类似的功能。而.net的打印预览控件却很遗憾的没有提供这一功能,只来自己想办法来实现啦。
呵呵,不过办法总是有的。
我的办法就是用代码来控制打印预览控件中的水平来垂直滚动条的位置,间接实现和用鼠标直接拖动滚动条一样的效果。
在实现这一功能的过程中,最大的困难是打印预览控件并没有让程序员直接调用的关于滚动条的方法或属性。所以只好向WinAPI求助了。
以下API函数和常量就是实现上述功能的关键了:
[DllImport("user32.dll")]
private static extern int SetScrollPos(IntPtr hwnd, int nBar, int nPos, bool bRedraw);
[DllImport("user32.dll")]
private static extern int GetScrollPos(IntPtr hwnd, int nBar);
[DllImport("user32.dll")]
private static extern bool PostMessage(IntPtr hWnd, int nBar, int wParam, int lParam);
[DllImport("user32", CharSet = CharSet.Auto)]
private static extern bool GetScrollRange(IntPtr hWnd, int nBar, out int lpMinPos, out int lpMaxPos);
private const int SB_HORZ = 0x0;
private const int SB_VERT = 0x1;
private const int WM_HSCROLL = 0x114;
private const int WM_VSCROLL = 0x115;
private const int SB_THUMBPOSITION = 4;
简单说明一下吧:
SetScrollPos:设置所指定滚动条中的滚动按钮的位置
GetScrollPos:获取指定滚动条的滚动按钮的位置
GetScrollRange:获取指定滚动条的滚动按钮的位置最大最小值
PostMessage:这个函数是关键中的关键,它负责向Windows控件发送相应的消息,以真正执行相应的操作。一些网友实现了滚动条中滑块位置的移动,但却没有引起控件中内容的移动,其原因就是因为没有调用这个函数,没有把移动内容的消息发送给控件。
SB_HORZ :代表水平滚动条
SB_VERT :代表垂直滚动条
WM_HSCROLL :代表水平滚动事件
WM_VSCROLL :代表垂直滚动事件
SB_THUMBPOSITION :至于这个常量,其含义我也不是很清楚,有知道的朋友欢迎回复给我。
好了,准备工作做好了,就可以开工了。
先声明几个变量:
bool Preview_move = false;//是否按下鼠标,表示处理移动状态。
Point MoveStart;//移动开始时,鼠标的坐标点
Point MoveEnd;//移动过程中鼠标的坐标点
在控件的MouseDown事件中,当鼠标按下时开始移动页面,并记下起始坐标点:
private void previewer_MouseDown(object sender, MouseEventArgs e)
{
Preview_move = true;
MoveStart = e.Location;
}
在控件的MouseUp事件中,记得当鼠标放开后要置回非移动状态:
private void previewer_MouseUp(object sender, MouseEventArgs e)
{
Preview_move = false;
}
以下就是实现移动页面的关键部分了,在控件的MouseMove实现用代码间接控制控件的滚动条位置并实现页面实时移动:
private void previewer_MouseMove(object sender, MouseEventArgs e)
{
if (!Preview_move) return;
MoveEnd = e.Location;
int MinH,MaxH,MinV,MaxV;
//获得鼠标在X和Y两个方向上的移动量。除以10是为是让移动页面的速度变慢一点。而前面的负号则是用来调节页面移动方向的。
int MoveX = -(MoveEnd.X - MoveStart.X)/10;
int MoveY = -(MoveEnd.Y - MoveStart.Y)/10;
//获取滚动条的最大最小位置和当前位置
GetScrollRange(previewer.Handle, 0, out MinH, out MaxH);
GetScrollRange(previewer.Handle, 1, out MinV, out MaxV);
int PosH = GetScrollPos(previewer.Handle, 0);
int PosV = GetScrollPos(previewer.Handle, 1);
//计算最终滚动条的位置(注意最终位置不要超出最大最小值的范围)
int PosH1 = PosH + MoveX;
if (PosH1 >= MinH && PosH1 <= MaxH)
{
SetScrollPos(previewer.Handle, SB_HORZ, PosH1, true);//设置滚动条的位置
PostMessage(previewer.Handle, WM_HSCROLL, SB_THUMBPOSITION + 0x10000 * PosH1, 0);//告诉控件移动页面内容到相应的位置上
}
int PosV1 = PosV + MoveY;
if (PosV1 >= MinV && PosV1 <= MaxV)
{
SetScrollPos(previewer.Handle, SB_VERT, PosV1, true);
PostMessage(previewer.Handle, WM_VSCROLL, SB_THUMBPOSITION + 0x10000 * PosV1, 0);
}
}
OK,一个能用鼠标实时移动页面内容的打印预览功能作好了。其实,对于.net中很多控件都可以用相似的方面实现对滚动条的控制。
C#中用鼠标移动页面功能的实现(代码控制滚动条)的更多相关文章
- Web前端 页面功能——点击按钮返回顶部的实现方法
1. 最简单的静态返回顶部,点击直接跳转页面顶部,常见于固定放置在页面底部返回顶部功能 方法一:用命名锚点击返回到顶部预设的id为top的元素 html代码 <a href="#top ...
- 实战使用Axure设计App,使用WebStorm开发(5) – 实现页面功能
系列文章 实战使用Axure设计App,使用WebStorm开发(1) – 用Axure描述需求 实战使用Axure设计App,使用WebStorm开发(2) – 创建 Ionic 项目 实战使 ...
- 网页引导:jQuery插件实现的页面功能介绍引导页效果
现在很多网站不仅是介绍,更多的是有一些功能,怎么样让客户快速的知道网站有哪些功能呢?这里pagewalkthrough.js插件能帮我们实现,它是一个轻量级的jQuery插件,它可以帮助我们创建一个遮 ...
- Unity3d 鼠标拣选小功能集合
最近在做一些优化工具,把鼠标拣选的功能单独抽出来. 可遍历所有选中的某类型资源,会递归文件夹 可编译所有prefab的某个Component,也是递归的 using UnityEngine; usin ...
- 微信平台接入Web页面功能接口(C#)
微信平台接入web页面功能接口 今年因工作需要,通过微信平台接入公司的Wap页面,回忆下,记录内容,方面以后使用. 1.成为开发者后,你才可以使用公众平台的开发功能.需要填写URL和ToKen,接口配 ...
- rockchip 3128 平台USB接口鼠标U盘功能调试日记
2019-04-12 关键词: rk3128 OTG.rk3128外接鼠标U盘.RK外接鼠标U盘 本篇文章是笔者根据自己当前所掌握知识对 rk3128 平台 USB 接口接鼠标实现输入功能调试的一个记 ...
- GoodUserInterface 模仿页面功能
模仿一些好的应用中的好的界面或功能.平时使用的APP有很多,其中一些都是常见的功能的拼凑,在业务层面比较复杂,而具体的页面实现都很类似.在这种情况下,我们还会发现有一些APP的页面效果的实现方式比较独 ...
- 第一章 “我要点爆”微信小程序云开发之项目建立与我的页面功能实现
第一章 “我要点爆”微信小程序云开发之项目建立与我的页面功能实现 开发环境搭建 使用自己的AppID新建小程序项目,后端服务选择小程序·云开发,点击新建,完成项目新建. 新建成功后跳转到开发者工具界面 ...
- jQuery插件实现的页面功能介绍引导页效果
新产品上线或是改版升级,我们会在用户第一次使用产品时建立一个使用向导,引导用户如何使用产品,如使用演示的方式逐一介绍界面上的功能模块,从而提升了用户体验和产品的亲和力. Helloweba.com之前 ...
随机推荐
- Linux下c++使用pthread库
pthread 库是纯c库,没有类指针的概念,当想phread_create中传递类成员函数时,就会报错,这里针对这种情况,对线程创建做了必要封装,较为简单,继承类,实现run接口,然后使用start ...
- 第四篇:python基础_4
本篇内容 名称空间与作用域 闭包函数 装饰器 迭代器 生成器 三元表达式 列表解析 生成器表达式 一. 名称空间与作用域 1.名称空间 存放名字的地方,准确的说名称空间是存放名字与变量值绑定关系的地方 ...
- BootStrap导入及其使用
BootStrap主要是一个CSS框架,用于页面布局 <!DOCTYPE html> <html lang="en"> <head> <m ...
- TOJ 4105 Lines Counting(离线树状数组)
4105. Lines Counting Time Limit: 2.0 Seconds Memory Limit: 150000K Total Runs: 152 Accepted Ru ...
- BZOJ3999 [TJOI2015]旅游 【树剖 + 线段树】
题目 为了提高智商,ZJY准备去往一个新世界去旅游.这个世界的城市布局像一棵树.每两座城市之间只有一条路径可 以互达.每座城市都有一种宝石,有一定的价格.ZJY为了赚取最高利益,她会选择从A城市买入再 ...
- Posix线程编程指南
Posix线程编程指南 Posix线程编程指南... 1 一线程创建与取消... 2 线程创建... 2 1.线程与进程... 2 2. 创建线程... 2 3. 线程创建属性... 2 4. 创建的 ...
- Python 错误类型及解决方法
SyntaxError: invalid syntax 表示“语法错误:不正确的语法” 检查代码的缩进,代码格式是否正确,Python的缩进一般为四个空格,tab键尽量不要用. In ...
- 开发人员为组件添加自定义的className
在开发过程当中需要给组件写上自己的样式,这个时候怎么办呢? 直接给组件添加className这样是无效的 当给组件添加className之后 在写组件的时候需要对使用你的组件的开发人员提供自定义cla ...
- [AGC002D] Stamp Rally (并查集+整体二分)
Description 给你一个n个点m个条边构成的简单无向连通图,有Q组询问,每次询问从两个点x,y走出两条路径,使这两条路径覆盖z个点,求得一种方案使得路径上经过的变的最大编号最小. Input ...
- 【HDOJ5521】Meeting(最短路)
题意:有n个点,m个点集,每个点集中有e[i]个点,同一点集的点互相之间到达需要t[i]单位的时间,求min(max(dis(1,i),dis(i,n))),i属于[1,n] 输出最小值并増序输出所有 ...