[转载自:http://www.chriskarcher.net/2008/01/26/hiding-the-progress-bar-of-a-net-20-cf-webbrowser]
One of the nice additions to the .NET 2.0 Compact Framework is the WebBrowser control. This control has always been present in the full framework , but to implement a web browser on the PocketPC you would have had to either write your own managed wrapper or use an existing one such as OpenNETCF’s HTMLViewer. But now that it’s included in the CF, we should give it a try. Many developers, myself included, use an embedded browser control to display rich, custom formatted content in their .NET apps. You can do this with the WebBrowser class by generating the HTML and setting the DocumentText property on the control. However, the new managed WebBrowser has a major drawback: Everytime you set the DocumentText property it shows a progress bar while loading the content into the browser. As far as I can tell, this behavior is only on Windows Mobile 5 devices, not on PocketPC 2003. Read on to figure out how to disable this behavior.
So, here’s what it looks like:
At first glance, it doesn’t look intrusive. But when you start updating the HTML regularly and the progress bar pops up every time, it starts to look out of place. It would be nice if MS just exposed an option to disable it, but they don’t. We’re going to have to do some work ourselves to get rid of it.
First, some background. In my application, I created a UserControl named WebBrowserPanel. WebBrowserPanel has a single WebBrowser child control which is anchored Top, Right, Bottom, and Left. It has the following constuctor to make it use all the available space:
- public WebBrowserPanel()
- {
- InitializeComponent();
- WebBrowser.Width = this .Width - 2;
- WebBrowser.Height = this .Height;
- }
public WebBrowserPanel() { InitializeComponent(); WebBrowser.Width = this.Width - 2; WebBrowser.Height = this.Height; }
Putting the WebBrowser inside a user control lets us give it a border and, as you’ll see later, will be crucial for this fix to work.
Using the Remote Spy tool that ships with VS 2005, we can examine the window structure of the application on the Windows Mobile 5 emulator:
The “MSPIE Status” window, a child of the “IExplore” window, looks interesting. Inspecting its properties shows us that it’s 23 pixels tall, and likely the progress bar we’re looking to hide. If we can get our hands on its window handle we can try to move, resize, or manipulate it in some other way to hide it. To get its window handle, I wrote the following function:
- public static IntPtr FindHwndByClass( string strClass, IntPtr parentHwnd)
- {
- StringBuilder sbClass = new StringBuilder(256);
- if (0 != GetClassName(parentHwnd, sbClass, sbClass.Capacity) && sbClass.ToString() == strClass)
- return parentHwnd;
- IntPtr hwndChild = GetWindow(parentHwnd, ( int )GetWindowFlags.GW_CHILD);
- while (hwndChild != IntPtr.Zero)
- {
- IntPtr result = FindHwndByClass(strClass, hwndChild);
- if (result != IntPtr.Zero)
- return result;
- hwndChild = GetWindow(hwndChild, ( int )GetWindowFlags.GW_HWNDNEXT);
- }
- return IntPtr.Zero;
- }
public static IntPtr FindHwndByClass(string strClass, IntPtr parentHwnd) { StringBuilder sbClass = new StringBuilder(256); if (0 != GetClassName(parentHwnd, sbClass, sbClass.Capacity) && sbClass.ToString() == strClass) return parentHwnd; IntPtr hwndChild = GetWindow(parentHwnd, (int)GetWindowFlags.GW_CHILD); while (hwndChild != IntPtr.Zero) { IntPtr result = FindHwndByClass(strClass, hwndChild); if (result != IntPtr.Zero) return result; hwndChild = GetWindow(hwndChild, (int)GetWindowFlags.GW_HWNDNEXT); } return IntPtr.Zero; }
We can pass in “MSPIE Status” as the class name and look for it as a child of the WebBrowser.
Now that we have the handle, we can try to hide it. My initial attempts to hide the progress bar included using SetWindowPos to move the bar off the screen, resize it to one pixel high, and a number of other hacks that didn’t work. As a last resort, I tried the ultimate: DestroyWindow . After initializing the WebBrowser in WebBrowserPanel’s constructor, I would find the status bar window and destroy it. This seemed to work, kind of. As you can see below, there are about 20 pixels of whitespace at the bottom of the browser, noticeable when you have enough content to need scrollbars:
Not good, but easy enough to work around. After we get the progress bar handle we can get its window height. After we destroy the window, we can resize the WebBrowser to be this much taller than its parent panel, thus clipping off this whitespace. WebBrowserPanel’s constructor now looks like:
- public WebBrowserPanel()
- {
- InitializeComponent();
- WebBrowser.Width = this .Width - 2;
- WebBrowser.Height = this .Height;
- IntPtr hwndStatus = FindHwndByClass( "MSPIE Status" , WebBrowser.Handle);
- if (hwndStatus != IntPtr.Zero)
- {
- RECT rectStatus = new RECT();
- GetClientRect(hwndStatus, out rectStatus);
- DestroyWindow(hwndStatus);
- WebBrowser.Height += rectStatus.Height;
- }
- }
public WebBrowserPanel() { InitializeComponent(); WebBrowser.Width = this.Width - 2; WebBrowser.Height = this.Height; IntPtr hwndStatus = FindHwndByClass("MSPIE Status", WebBrowser.Handle); if (hwndStatus != IntPtr.Zero) { RECT rectStatus = new RECT(); GetClientRect(hwndStatus, out rectStatus); DestroyWindow(hwndStatus); WebBrowser.Height += rectStatus.Height; } }
And we end up with:
Success! You can now set the DocumentText any number of times without the progress bar showing up.
The code presented above makes use of the following PInvokes and enums:
- [DllImport( "coredll.dll" )]
- public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
- [DllImport( "coredll.dll" )]
- public static extern IntPtr GetWindow(IntPtr hwnd, int cmd);
- public enum GetWindowFlags : int
- {
- GW_HWNDFIRST = 0,
- GW_HWNDLAST = 1,
- GW_HWNDNEXT = 2,
- GW_HWNDPREV = 3,
- GW_OWNER = 4,
- GW_CHILD = 5,
- GW_MAX = 5
- }
- [DllImport( "coredll.dll" )]
- public static extern bool DestroyWindow(IntPtr hwnd);
- [StructLayout(LayoutKind.Sequential)]
- public struct RECT
- {
- public int X;
- public int Y;
- public int Width;
- public int Height;
- }
- [DllImport( "coredll.dll" )]
- static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
[DllImport("coredll.dll")] public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); [DllImport("coredll.dll")] public static extern IntPtr GetWindow(IntPtr hwnd, int cmd); public enum GetWindowFlags : int { GW_HWNDFIRST = 0, GW_HWNDLAST = 1, GW_HWNDNEXT = 2, GW_HWNDPREV = 3, GW_OWNER = 4, GW_CHILD = 5, GW_MAX = 5 } [DllImport("coredll.dll")] public static extern bool DestroyWindow(IntPtr hwnd); [StructLayout(LayoutKind.Sequential)] public struct RECT { public int X; public int Y; public int Width; public int Height; } [DllImport("coredll.dll")] static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
相关推荐
设置隐试打开PPT报错 Hiding the application window is not allowed
Based on the provided information from the book "C# 3.0 With the .NET Framework 3.5 Unleashed," we can extract several key points and concepts that are essential for understanding the fundamentals of ...
标题中的“精品软件工具--A CLI tool for hiding the application's icon in the.zip”指的是一个命令行界面(CLI)工具,其主要功能是隐藏应用程序图标。这个工具可能是为那些希望在不删除或禁用应用本身的情况下,...
em bedding and coding are synchronous,i.e.a fusion of the inform ation data of secret and public speech. It can em — bed dynam ic data bits of secret speech into public speech, with perfect info...
ConfuserEx 支持 .NET 框架 2.0 - 4.5 和 Mono (还有其他 .NET 框架): Symbol 重命名 WPF/BAML 重命名 Control flow obfuscation Method reference hiding Anti debuggers/profilers Anti memory dumping Anti ...
OPC 客户端The FactorySoft OPC Server (FSServer) DLL provides an easy-to-use interface by hiding the details that are common to most OPC servers. The division between application and FSServer DLL is at...
The Role of C# in the .NET Enterprise Architecture 24 Summary 26 Chapter 2: C# Basics 29 Before We Start 30 Our First C# Program 30 The Code 30 Compiling and Running the Program 31 Contents A Closer ...
数据隐藏(Data Hiding)是一种重要的信息安全技术,旨在将秘密信息隐匿于普通的数字载体之中,如图像、音频或视频等。这种方法不仅能够保护信息不被轻易察觉,还能在一定程度上抵御对数据的恶意篡改。本文主要介绍...
lsb code..which helps in hiding the secret image within another image...so the image will be secured the intruder.
标题提到的论文《Design of a Reversible Data Hiding Algorithm Based on Dynamic DC-QIM.pdf》便是关于可逆数据隐藏算法的研究,特别是基于动态失真补偿量化索引调制(Dynamic DC-QIM)的算法设计。动态DC-QIM是相...
- Displaying the icon of a GameObject - Showing / hiding a GameObject - Locking / unlocking a GameObject - Prevent selection of locked GameObject - Displaying tag and layer of a GameObject - ...
Python, a high-level and versatile programming language, offers numerous libraries and frameworks that facilitate the development of image processing and information hiding applications. The LSB ...
And Now, the Rest of the Story What You Get Out of It Inside the Manifest In the Beginning, There Was the Root, And It Was Good Permissions, Instrumentations, and Applications (Oh My!) Your ...
This file Image stegenography is one of the best method of information hiding i.e. text in an image
数据隐藏与深度学习:一种统一数字水印和隐写术的调查 在当前数字化时代,随着音频、视频和图像等多媒体数据的普及,数据隐藏技术的重要性日益凸显。数据隐藏是将信息嵌入到噪声容忍的信号中,如音频片段、视频剪辑...
proposed method keeps the excellences of hiding watermark by using the region of motion vectors. The capacity of watermark can be increased by choosing more macroblocks to the watermarks.
It will cover all the tracks of the running programs and their windows by hiding them also from the task bar. In addition to that Boss Key will not close the applications but keep them hidden in the ...
Hiding Behind the Keyboard Uncovering Covert Communication Methods with Forensic Analysis 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请...
To improve the iris feature template data security, a data hiding approach based on bit streams is proposed, in which an iris feature template is embedded into a face image. The proposed approach is ...
The software architecture of a system is the structures of the system, which comprise software components, the externally visible properties of those components, and the relationships among them....