WPF 后台模拟界面触摸点击

win32Api提供一种方法,模拟用户触摸点击

InjectTouchInput function

  • InitializeTouchInjection
  • InjectTouchInput

在模拟添加触摸输入(InjectTouchInput)前,需要提前初始化(InitializeTouchInjection)

  1     /// <summary>
  2     /// Use this Classes static methods to initialize and inject touch input.
  3     /// </summary>
  4     public class NativeMethods
  5     {
  6         /// <summary>
  7         /// Call this first to initialize the TouchInjection!
  8         /// </summary>
  9         /// <param name="maxCount">The maximum number of touch points to simulate. Must be less than 256!</param>
 10         /// <param name="feedbackMode">Specifies the visual feedback mode of the generated touch points</param>
 11         /// <returns>true if success</returns>
 12         [DllImport("User32.dll")]
 13         public static extern bool InitializeTouchInjection(uint maxCount = 256, TouchFeedback feedbackMode = TouchFeedback.DEFAULT);
 14
 15         /// <summary>
 16         /// Inject an array of POINTER_TUCH_INFO
 17         /// </summary>
 18         /// <param name="count">The exact number of entries in the array</param>
 19         /// <param name="contacts">The POINTER_TOUCH_INFO to inject</param>
 20         /// <returns>true if success</returns>
 21         [DllImport("User32.dll")]
 22         public static extern bool InjectTouchInput(int count, [MarshalAs(UnmanagedType.LPArray), In] PointerTouchInfo[] contacts);
 23     }
 24
 25     static class IdGenerator
 26     {
 27         static private int _int;
 28         private static uint _uint;
 29         private static readonly object _mutex = new object();
 30
 31         public static int GetUniqueInt()
 32         {
 33             Interlocked.Increment(ref _int);
 34             return _int;
 35         }
 36
 37         public static uint GetUinqueUInt()
 38         {
 39             lock (_mutex)
 40             {
 41                 if (_uint > 256)
 42                 {
 43                     ResetUint();
 44                 }
 45                 if (_uint == uint.MaxValue)
 46                     throw new IndexOutOfRangeException();
 47                 else
 48                 {
 49                     _uint++;
 50                     return _uint;
 51                 }
 52             }
 53         }
 54
 55         public static void ResetUint()
 56         {
 57             lock (_mutex)
 58             {
 59                 _uint = uint.MinValue;
 60             }
 61         }
 62     }
 63
 64     #region Types
 65     /// <summary>
 66     /// Enum of touch visualization options
 67     /// </summary>
 68     public enum TouchFeedback
 69     {
 70         /// <summary>
 71         /// Specifies default touch visualizations.
 72         /// </summary>
 73         DEFAULT = 0x1,
 74         /// <summary>
 75         /// Specifies indirect touch visualizations.
 76         /// </summary>
 77         INDIRECT = 0x2,
 78         /// <summary>
 79         /// Specifies no touch visualizations.
 80         /// </summary>
 81         NONE = 0x3
 82     }
 83
 84     /// <summary>
 85     /// The contact area.
 86     /// </summary>
 87     [StructLayout(LayoutKind.Explicit)]
 88     public struct ContactArea
 89     {
 90         [FieldOffset(0)]
 91         public int left;
 92         [FieldOffset(4)]
 93         public int top;
 94         [FieldOffset(8)]
 95         public int right;
 96         [FieldOffset(12)]
 97         public int bottom;
 98     }
 99
100     /// <summary>
101     /// Values that can appear in the TouchMask field of the PointerTouchInfo structure
102     /// </summary>
103     public enum TouchFlags
104     {
105         /// <summary>
106         /// Indicates that no flags are set.
107         /// </summary>
108         NONE = 0x00000000
109     }
110
111     /// <summary>
112     /// Values that can appear in the TouchMask field of the PointerTouchInfo structure.
113     /// </summary>
114     public enum TouchMask
115     {
116         /// <summary>
117         /// Default. None of the optional fields are valid.
118         /// </summary>
119         NONE = 0x00000000,
120         /// <summary>
121         /// The ContactArea field is valid
122         /// </summary>
123         CONTACTAREA = 0x00000001,
124         /// <summary>
125         /// The orientation field is valid
126         /// </summary>
127         ORIENTATION = 0x00000002,
128         /// <summary>
129         /// The pressure field is valid
130         /// </summary>
131         PRESSURE = 0x00000004
132     }
133
134     /// <summary>
135     /// Values that can appear in the PointerFlags field of the PointerInfo structure.
136     /// </summary>
137     public enum PointerFlags
138     {
139         /// <summary>
140         /// Default
141         /// </summary>
142         NONE = 0x00000000,
143         /// <summary>
144         /// Indicates the arrival of a new pointer
145         /// </summary>
146         NEW = 0x00000001,
147         /// <summary>
148         /// Indicates that this pointer continues to exist. When this flag is not set, it indicates the pointer has left detection range.
149         /// This flag is typically not set only when a hovering pointer leaves detection range (PointerFlag.UPDATE is set) or when a pointer in contact with a window surface leaves detection range (PointerFlag.UP is set).
150         /// </summary>
151         INRANGE = 0x00000002,
152         /// <summary>
153         /// Indicates that this pointer is in contact with the digitizer surface. When this flag is not set, it indicates a hovering pointer.
154         /// </summary>
155         INCONTACT = 0x00000004,
156         /// <summary>
157         /// Indicates a primary action, analogous to a mouse left button down.
158         ///A touch pointer has this flag set when it is in contact with the digitizer surface.
159         ///A pen pointer has this flag set when it is in contact with the digitizer surface with no buttons pressed.
160         ///A mouse pointer has this flag set when the mouse left button is down.
161         /// </summary>
162         FIRSTBUTTON = 0x00000010,
163         /// <summary>
164         /// Indicates a secondary action, analogous to a mouse right button down.
165         /// A touch pointer does not use this flag.
166         /// A pen pointer has this flag set when it is in contact with the digitizer surface with the pen barrel button pressed.
167         /// A mouse pointer has this flag set when the mouse right button is down.
168         /// </summary>
169         SECONDBUTTON = 0x00000020,
170         /// <summary>
171         /// Indicates a secondary action, analogous to a mouse right button down.
172         /// A touch pointer does not use this flag.
173         /// A pen pointer does not use this flag.
174         /// A mouse pointer has this flag set when the mouse middle button is down.
175         /// </summary>
176         THIRDBUTTON = 0x00000040,
177         /// <summary>
178         /// Indicates actions of one or more buttons beyond those listed above, dependent on the pointer type. Applications that wish to respond to these actions must retrieve information specific to the pointer type to determine which buttons are pressed. For example, an application can determine the buttons states of a pen by calling GetPointerPenInfo and examining the flags that specify button states.
179         /// </summary>
180         OTHERBUTTON = 0x00000080,
181         /// <summary>
182         /// Indicates that this pointer has been designated as primary. A primary pointer may perform actions beyond those available to non-primary pointers. For example, when a primary pointer makes contact with a window’s surface, it may provide the window an opportunity to activate by sending it a WM_POINTERACTIVATE message.
183         /// </summary>
184         PRIMARY = 0x00000100,
185         /// <summary>
186         /// Confidence is a suggestion from the source device about whether the pointer represents an intended or accidental interaction, which is especially relevant for PT_TOUCH pointers where an accidental interaction (such as with the palm of the hand) can trigger input. The presence of this flag indicates that the source device has high confidence that this input is part of an intended interaction.
187         /// </summary>
188         CONFIDENCE = 0x00000200,
189         /// <summary>
190         /// Indicates that the pointer is departing in an abnormal manner, such as when the system receives invalid input for the pointer or when a device with active pointers departs abruptly. If the application receiving the input is in a position to do so, it should treat the interaction as not completed and reverse any effects of the concerned pointer.
191         /// </summary>
192         CANCELLED = 0x00000400,
193         /// <summary>
194         /// Indicates that this pointer just transitioned to a “down” state; that is, it made contact with the window surface.
195         /// </summary>
196         DOWN = 0x00010000,
197         /// <summary>
198         /// Indicates that this information provides a simple update that does not include pointer state changes.
199         /// </summary>
200         UPDATE = 0x00020000,
201         /// <summary>
202         /// Indicates that this pointer just transitioned to an “up” state; that is, it broke contact with the window surface.
203         /// </summary>
204         UP = 0x00040000,
205         /// <summary>
206         /// Indicates input associated with a pointer wheel. For mouse pointers, this is equivalent to the action of the mouse scroll wheel (WM_MOUSEWHEEL).
207         /// </summary>
208         WHEEL = 0x00080000,
209         /// <summary>
210         /// Indicates input associated with a pointer h-wheel. For mouse pointers, this is equivalent to the action of the mouse horizontal scroll wheel (WM_MOUSEHWHEEL).
211         /// </summary>
212         HWHEEL = 0x00100000
213     }
214
215     /// <summary>
216     /// The TouchPoint structure defines the x- and y- coordinates of a point.
217     /// </summary>
218     [StructLayout(LayoutKind.Sequential)]
219     public struct TouchPoint
220     {
221         /// <summary>
222         /// The x-coordinate of the point.
223         /// </summary>
224         public int X;
225         /// <summary>
226         /// The y-coordinate of the point.
227         /// </summary>
228         public int Y;
229     }
230
231     /// <summary>
232     /// Identifies the pointer input types.
233     /// </summary>
234     public enum PointerInputType
235     {
236         /// <summary>
237         /// Generic pointer type. This type never appears in pointer messages or pointer data. Some data query functions allow the caller to restrict the query to specific pointer type. The PT_POINTER type can be used in these functions to specify that the query is to include pointers of all types
238         /// </summary>
239         POINTER = 0x00000001,
240         /// <summary>
241         /// Touch pointer type.
242         /// </summary>
243         TOUCH = 0x00000002,
244         /// <summary>
245         /// Pen pointer type.
246         /// </summary>
247         PEN = 0x00000003,
248         /// <summary>
249         /// Mouse pointer type
250         /// </summary>
251         MOUSE = 0x00000004,
252         /// <summary>
253         /// touchpad pointer type
254         /// </summary>
255         TOUCHPAD = 0x00000005
256     };
257
258     /// <summary>
259     /// Contains basic pointer information common to all pointer types. Applications can retrieve this information using the GetPointerInfo, GetPointerFrameInfo, GetPointerInfoHistory and GetPointerFrameInfoHistory functions.
260     /// </summary>
261     [StructLayout(LayoutKind.Sequential)]
262     public struct PointerInfo
263     {
264         /// <summary>
265         /// A value from the PointerInputType enumeration that specifies the pointer type.
266         /// </summary>
267         public PointerInputType pointerType;
268
269         /// <summary>
270         /// An identifier that uniquely identifies a pointer during its lifetime. A pointer comes into existence when it is first detected and ends its existence when it goes out of detection range. Note that if a physical entity (finger or pen) goes out of detection range and then returns to be detected again, it is treated as a new pointer and may be assigned a new pointer identifier.
271         /// </summary>
272         public uint PointerId;
273
274         /// <summary>
275         /// An identifier common to multiple pointers for which the source device reported an update in a single input frame. For example, a parallel-mode multi-touch digitizer may report the positions of multiple touch contacts in a single update to the system.
276         /// Note that frame identifier is assigned as input is reported to the system for all pointers across all devices. Therefore, this field may not contain strictly sequential values in a single series of messages that a window receives. However, this field will contain the same numerical value for all input updates that were reported in the same input frame by a single device.
277         /// </summary>
278         public uint FrameId;
279
280         /// <summary>
281         /// May be any reasonable combination of flags from the Pointer Flags constants.
282         /// </summary>
283         public PointerFlags PointerFlags;
284
285         /// <summary>
286         /// Handle to the source device that can be used in calls to the raw input device API and the digitizer device API.
287         /// </summary>
288         public IntPtr SourceDevice;
289
290         /// <summary>
291         /// Window to which this message was targeted. If the pointer is captured, either implicitly by virtue of having made contact over this window or explicitly using the pointer capture API, this is the capture window. If the pointer is uncaptured, this is the window over which the pointer was when this message was generated.
292         /// </summary>
293         public IntPtr WindowTarget;
294
295         /// <summary>
296         /// Location in screen coordinates.
297         /// </summary>
298         public TouchPoint PtPixelLocation;
299
300         /// <summary>
301         /// Location in device coordinates.
302         /// </summary>
303         public TouchPoint PtPixelLocationRaw;
304
305         /// <summary>
306         /// Location in HIMETRIC units.
307         /// </summary>
308         public TouchPoint PtHimetricLocation;
309
310         /// <summary>
311         /// Location in device coordinates in HIMETRIC units.
312         /// </summary>
313         public TouchPoint PtHimetricLocationRaw;
314
315         /// <summary>
316         /// A message time stamp assigned by the system when this input was received.
317         /// </summary>
318         public uint Time;
319
320         /// <summary>
321         /// Count of inputs that were coalesced into this message. This count matches the total count of entries that can be returned by a call to GetPointerInfoHistory. If no coalescing occurred, this count is 1 for the single input represented by the message.
322         /// </summary>
323         public uint HistoryCount;
324
325         /// <summary>
326         /// A value whose meaning depends on the nature of input.
327         /// When flags indicate PointerFlag.WHEEL, this value indicates the distance the wheel is rotated, expressed in multiples or factors of WHEEL_DELTA. A positive value indicates that the wheel was rotated forward and a negative value indicates that the wheel was rotated backward.
328         /// When flags indicate PointerFlag.HWHEEL, this value indicates the distance the wheel is rotated, expressed in multiples or factors of WHEEL_DELTA. A positive value indicates that the wheel was rotated to the right and a negative value indicates that the wheel was rotated to the left.
329         /// </summary>
330         public uint InputData;
331
332         /// <summary>
333         /// Indicates which keyboard modifier keys were pressed at the time the input was generated. May be zero or a combination of the following values.
334         /// POINTER_MOD_SHIFT – A SHIFT key was pressed.
335         /// POINTER_MOD_CTRL – A CTRL key was pressed.
336         /// </summary>
337         public uint KeyStates;
338
339         /// <summary>
340         /// TBD
341         /// </summary>
342         public ulong PerformanceCount;
343
344         /// <summary>
345         /// ???
346         /// </summary>
347         public PointerButtonChangeType ButtonChangeType;
348     }
349
350     /// <summary>
351     /// Enumeration of PointerButtonChangeTypes
352     /// </summary>
353     public enum PointerButtonChangeType
354     {
355         NONE,
356         FIRSTBUTTON_DOWN,
357         FIRSTBUTTON_UP,
358         SECONDBUTTON_DOWN,
359         SECONDBUTTON_UP,
360         THIRDBUTTON_DOWN,
361         THIRDBUTTON_UP,
362         FOURTHBUTTON_DOWN,
363         FOURTHBUTTON_UP,
364         FIFTHBUTTON_DOWN,
365         FIFTHBUTTON_UP
366     }
367
368     /// <summary>
369     /// Contains information about a ‘contact‘ (coordinates, size, pressure...)
370     /// </summary>
371     [StructLayout(LayoutKind.Sequential)]
372     public struct PointerTouchInfo
373     {
374         ///<summary>
375         /// Contains basic pointer information common to all pointer types.
376         ///</summary>
377         public PointerInfo PointerInfo;
378
379         ///<summary>
380         /// Lists the touch flags.
381         ///</summary>
382         public TouchFlags TouchFlags;
383
384         /// <summary>
385         /// Indicates which of the optional fields contain valid values. The member can be zero or any combination of the values from the Touch Mask constants.
386         /// </summary>
387         public TouchMask TouchMasks;
388
389         ///<summary>
390         /// Pointer contact area in pixel screen coordinates.
391         /// By default, if the device does not report a contact area,
392         /// this field defaults to a 0-by-0 rectangle centered around the pointer location.
393         ///</summary>
394         public ContactArea ContactArea;
395
396         /// <summary>
397         /// A raw pointer contact area.
398         /// </summary>
399         public ContactArea ContactAreaRaw;
400
401         ///<summary>
402         /// A pointer orientation, with a value between 0 and 359, where 0 indicates a touch pointer
403         /// aligned with the x-axis and pointing from left to right; increasing values indicate degrees
404         /// of rotation in the clockwise direction.
405         /// This field defaults to 0 if the device does not report orientation.
406         ///</summary>
407         public uint Orientation;
408
409         ///<summary>
410         /// Pointer pressure normalized in a range of 0 to 256.
411         ///</summary>
412         public uint Pressure;
413
414         /// <summary>
415         /// Move the touch point, together with its ContactArea
416         /// </summary>
417         /// <param name="deltaX">the change in the x-value</param>
418         /// <param name="deltaY">the change in the y-value</param>
419         public void Move(int deltaX, int deltaY)
420         {
421             PointerInfo.PtPixelLocation.X += deltaX;
422             PointerInfo.PtPixelLocation.Y += deltaY;
423             ContactArea.left += deltaX;
424             ContactArea.right += deltaX;
425             ContactArea.top += deltaY;
426             ContactArea.bottom += deltaY;
427         }
428     }
429     #endregion

我们模拟触摸A(100,100)并移动到(500,500):

提前初始化“触摸注入”

1     private void MainWindow_Loaded(object sender, RoutedEventArgs e)
2     {
3         NativeMethods.InitializeTouchInjection();
4     }

模拟触摸移动:

 1     private void FakeTouchMove(int fromX, int fromY, int toX, int toY)
 2     {
 3         // Touch Down
 4         PointerTouchInfo contact = MakePointerTouchInfo(fromX, fromY, 5, 1);
 5         PointerFlags oFlags = PointerFlags.DOWN | PointerFlags.INRANGE | PointerFlags.INCONTACT;
 6         contact.PointerInfo.PointerFlags = oFlags;
 7         NativeMethods.InjectTouchInput(1, new[] { contact });
 8
 9         // Touch Move
10         int movedX = toX - fromX;
11         int movedY = toY - fromY;
12         contact.Move(movedX, movedY);
13         oFlags = PointerFlags.INRANGE | PointerFlags.INCONTACT | PointerFlags.UPDATE;
14         contact.PointerInfo.PointerFlags = oFlags;
15         NativeMethods.InjectTouchInput(1, new[] { contact });
16
17         // Touch Up
18         contact.PointerInfo.PointerFlags = PointerFlags.UP;
19         NativeMethods.InjectTouchInput(1, new[] { contact });
20     }
21     private PointerTouchInfo MakePointerTouchInfo(int x, int y, int radius,
22         uint orientation = 90, uint pressure = 32000)
23     {
24         PointerTouchInfo contact = new PointerTouchInfo();
25         contact.PointerInfo.pointerType = PointerInputType.TOUCH;
26         contact.TouchFlags = TouchFlags.NONE;
27         contact.Orientation = orientation;
28         contact.Pressure = pressure;
29         contact.TouchMasks = TouchMask.CONTACTAREA | TouchMask.ORIENTATION | TouchMask.PRESSURE;
30         contact.PointerInfo.PtPixelLocation.X = x;
31         contact.PointerInfo.PtPixelLocation.Y = y;
32         uint unPointerId = IdGenerator.GetUinqueUInt();
33         Console.WriteLine("PointerId    " + unPointerId);
34         contact.PointerInfo.PointerId = unPointerId;
35         contact.ContactArea.left = x - radius;
36         contact.ContactArea.right = x + radius;
37         contact.ContactArea.top = y - radius;
38         contact.ContactArea.bottom = y + radius;
39         return contact;
40     }

界面接收触摸消息:

使用InjectTouchInput函数模拟触摸,Touch、Stylus消息都可以接收到。

 1     private Line _proxyLine;
 2     private void MainWindow_TouchDown(object sender, TouchEventArgs e)
 3     {
 4         System.Windows.Input.TouchPoint oPos = e.GetTouchPoint(this);
 5         Line oLine = new Line();
 6         oLine.Stroke = new SolidColorBrush(Colors.Red);
 7         oLine.StrokeThickness = 2;
 8         oLine.X1 = oPos.Position.X;
 9         oLine.Y1 = oPos.Position.Y;
10         _proxyLine = oLine;
11         Console.WriteLine("TouchDown;TouchID " + e.TouchDevice.Id + "  TouchDown " + oPos.Position.X + "    " + oPos.Position.Y);
12     }
13
14     private void MainWindow_TouchMove(object sender, TouchEventArgs e)
15     {
16         System.Windows.Input.TouchPoint movedPoint = e.GetTouchPoint(this);
17         Console.WriteLine("TouchMove:TouchID " + e.TouchDevice.Id + " TouchMove " + movedPoint.Position.X + "    " + movedPoint.Position.Y);
18     }
19
20     private void MainWindow_TouchUp(object sender, TouchEventArgs e)
21     {
22         System.Windows.Input.TouchPoint oPos = e.GetTouchPoint(this);
23         this._proxyLine.X2 = oPos.Position.X;
24         this._proxyLine.Y2 = oPos.Position.Y;
25         RootGrid.Children.Add(this._proxyLine);
26         Console.WriteLine("TouchUp:TouchID " + e.TouchDevice.Id + " TouchUp " + oPos.Position.X + "    " + oPos.Position.Y);
27     }

触摸模拟结果:

原文地址:https://www.cnblogs.com/kybs0/p/11969733.html

时间: 2024-11-13 08:02:33

WPF 后台模拟界面触摸点击的相关文章

使用WPF技术模拟手机界面

原文:使用WPF技术模拟手机界面 1. 前言 WPF(Windows Presentation Foundation),即"Windows呈现基础",它的目的非常明确,就是用来把数据"显示"给用户看的(说白了就是用来做UI的).接下来将会介绍一个小项目,用WPF来实现模拟手机界面设计. 2. 实现的功能 本项目模拟手机界面,实现了如下几个功能: 滑动解锁 顶部状态栏显示 查看系统时间 附有背景以及应用图标的界面及切换 点击日历图标跳转到显示日历的界面 点击锁屏图标进

wpf,后台触发按钮点击以及拖动

触发按钮Click MouseButtonEventArgs args = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left); args.RoutedEvent = Button.ClickEvent; btnOkCommand.RaiseEvent(args); 触发按钮绑定的Command 需要添加UIAutomationProvider 引用 ButtonAutomationPeer bam = new B

Wix 安装部署教程(九) --用WPF做安装界面

经常安装PC端的应用,特别是重装系统之后,大致分为两类.一类像QQ,搜狗输入法这样的.分三步走的:第一个页面可以自定义安装路径和软件许可.第二个页面显示安装进度条,第三个页面推荐其他应用.先不管人家怎么实现的,我们先回顾一下. QQ:       再一个就是分六步或七步走的,如QQ影音:欢迎界面,用户许可,安装组件,安装目录,安装进度,安装完成,有七步的,一般会多一些软件推荐.当然还有其他的,比如是基于ClickOnce打包的,就一个界面,一个进度条.没有安装目录选择,这一般不是商业软件.先说第

[WPF]绑定到界面的数组不支持调度线程以外对其更改的办法

[原]WPF编程经常遇到一个问题: 某个数组己绑定到主界面某控件中,然后在后台程序中需要对数组增(减)数据,然后程序就会报错, 程序提示:该类型的CollectionView 不支持从调度程序线程以外的线程对其SourceCollection进行的更改. 如下图所示: 既然不能这样操作,就得想一个办法来解决,现在先把把出现错误的程序全部列出来,然后再来根据解决办法进行修改, 本测试程序先建一个学生类: using System; using System.Collections.Generic;

C# WPF 一个设计界面

微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. C# WPF 一个设计界面 今天正月初三,大家在家呆着挺好,不要忘了自我充电. 武汉人民加油,今早又有噩耗,24号(8号)一路走好. 阅读导航 本文背景 代码实现 本文参考 源码 1. 本文背景 一个不错的界面设计 2. 代码实现 使用 .NET Framework 4.8 创建名为 "Dashboard1" 的WPF模板项目,添加3个Nuget库:MaterialDesignTh

Django后台管理界面

之前的几篇记录了模板视图.模型等页面展示的相关内容,这篇主要写一下后台admin管理界面的内容. 激活管理界面 Django管理站点完全是可选择的,之前我们是把这些功能给屏蔽掉了.记得上篇中Django模型模型安装小结中,我们把settings.py中的部分内容屏蔽了,并添加了一个app,如下 1 INSTALLED_APPS = ( 2 ## 'django.contrib.admin', 3 ## 'django.contrib.auth', 4 ## 'django.contrib.con

BOS v2.0后台管理系统界面通用解决方案

错误:java.net.BindException: Address already in use: JVM_Bind <null>:8080解决: cmd 窗口 --- 执行 netstat -ano 查看哪个进程占用端口 – 在任务管理器 结束进程优先关闭 java 进程 ,大多是重复启动 tomcat 造成1. 后台管理系统界面分析 界面效果 可以使用 frameset 框架来完成布局正文内容两种实现方案1. 使用 ajax 加载内容 ,很难实现独立刷新 2. 嵌入 iframe ,实现

4、VS2010+ASP.NET MVC4+EF4+JqueryEasyUI+Oracle项目开发之——后台管理界面

这一章节比较简单,我就直接贴代码了,后台管理登陆界面如下: 对应的控制器HomeController.cs,代码如下: using YKT.Model; using YKT.Common; using YKT.BLL; using YKT.Common.HtmlHelpers; using YKT.Common.Functions; using Microsoft.Practices.Unity; using YKT.IBLL; namespace YKT.Controllers { publi

HttpWebRequest 模拟登录响应点击事件(开源自己用的HttpHelper类)

平时也经常采集网站数据,也做模拟登录,但一般都是html控件POST到页面登录:还没有遇到用户服务器控件button按钮点击事件登录的,今天像往常一样POST传递参数,但怎么都能登录不了:最后发现还有两个参数需要传,__EVENTVALIDATION和__VIEWSTATE 在传的过程中需要对参数值进行URL编码 System.Web.HttpUtility.UrlEncode(value) 模拟登录代码:在本地写的一个测试的网站来模拟登录,原理都一样: Request request = ne