我正在为 windows mobile 6.5(c#、.net、compact 框架)开发一个应用程序,我很难找到如何在不使用默认滚动条的情况下上下拖动我的表单。我的表单比设备的屏幕大,我不希望用户使用默认滚动条,而是拖动表单。
关于如何做到这一点的任何想法?
谢谢
我正在为 windows mobile 6.5(c#、.net、compact 框架)开发一个应用程序,我很难找到如何在不使用默认滚动条的情况下上下拖动我的表单。我的表单比设备的屏幕大,我不希望用户使用默认滚动条,而是拖动表单。
关于如何做到这一点的任何想法?
谢谢
Thorsten 是对的,表单创建被硬编码到任何 Compact Framework 运行时中,您不能创建非全屏表单(这是窗口视图中的对话框)。
如果您开始在 VS (2003/2005/2008) 中开发本机 C/C++ Windows CE 项目,则窗口大小可以自由定义。
但是,创建后使用pinvoke更改窗体的窗口样式,您可以拥有一个可移动的窗口窗体:
在应用(相同的)窗口样式并稍微调整大小之后:
这是 C# Compact Framework 的代码片段:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
namespace MovableForm
{
class winapi
{
public static void moveWindow(System.Windows.Forms.Form form){
SetWindowPos(form.Handle, (IntPtr) HWNDPOS.HWND_TOPMOST, form.Left + 10, form.Top + 10, form.Width - 20, form.Height - 20, (uint)SWP.SWP_SHOWWINDOW);
}
public static void setStyle(System.Windows.Forms.Form frm)
{
uint oldStyle = getStyle(frm);
uint newStyle = (uint)(
WINSTYLES.WS_OVERLAPPED | WINSTYLES.WS_POPUP | WINSTYLES.WS_VISIBLE |
//WINSTYLES.WS_SYSMENU | // add if you need a X to close
WINSTYLES.WS_CAPTION | WINSTYLES.WS_BORDER | //WINSTYLES.WS_DLGFRAME | WINSTYLES.WS_MAXIMIZEBOX |
WINSTYLES.WS_POPUPWINDOW);
int iRet = SetWindowLong(frm.Handle, (int)GWL.GWL_STYLE, (int)newStyle);
//if returned iRet is zero we got an error
int newExStyle = GetWindowLong(frm.Handle, (int)GWL.GWL_EXSTYLE);
newExStyle = (int)((uint)newExStyle - (uint) WINEXSTYLES.WS_EX_CAPTIONOKBTN); //remove OK button
iRet = SetWindowLong(frm.Handle, (int)GWL.GWL_EXSTYLE, (int)newExStyle);
moveWindow(frm);
frm.Refresh();
}
//great stuff by http://ideas.dalezak.ca/2008/11/enumgetvalues-in-compact-framework.html
public static IEnumerable<Enum> GetValues(Enum enumeration)
{
List<Enum> enumerations = new List<Enum>();
foreach (FieldInfo fieldInfo in enumeration.GetType().GetFields(
BindingFlags.Static | BindingFlags.Public))
{
enumerations.Add((Enum)fieldInfo.GetValue(enumeration));
}
return enumerations;
}
...
然后是我使用的枚举(对不起所有的转换,我不明白,为什么标志在 API 调用中被定义为 int):
[DllImport("coredll.dll", SetLastError = true)]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("coredll.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
//non-fullscreen window (ex zDump) = WS_STYLE=0x90c9004, WS_EX_STYLE=0x00000008
//WS_POPUP | WS_VISIBLE
enum GWL:int{
GWL_STYLE = -16,
GWL_EXSTYLE = -20,
}
[Flags]
enum WINSTYLES:uint{
WS_OVERLAPPED = 0x00000000, //#define WS_OVERLAPPED WS_BORDER | WS_CAPTION
WS_POPUP= 0x80000000,
WS_VISIBLE= 0x10000000,
WS_MINIMIZE= 0x20000000,
WS_CLIPSIBLINGS= 0x04000000,
WS_CLIPCHILDREN= 0x02000000,
WS_DISABLED= 0x08000000,
WS_MAXIMIZE= 0x01000000,
WS_CAPTION = 0x00C00000, //#define WS_CAPTION 0x00C00000L /* WS_BORDER | WS_DLGFRAME */
WS_BORDER= 0x00800000,
WS_DLGFRAME= 0x00400000,
WS_VSCROLL= 0x00200000,
WS_HSCROLL= 0x00100000,
WS_SYSMENU= 0x00080000,
WS_THICKFRAME= 0x00040000,
WS_MINIMIZEBOX= 0x00020000,
WS_MAXIMIZEBOX= 0x00010000,
WS_POPUPWINDOW= 0x80880000, // Creates a pop-up window with WS_BORDER, WS_POPUP, and WS_SYSMENU styles. The WS_CAPTION and WS_POPUPWINDOW styles must be combined to make the window menu visible.
}
enum WINEXSTYLES:uint{
WS_EX_DLGMODALFRAME = 0x00000001,
WS_EX_TOPMOST = 0x00000008,
WS_EX_TOOLWINDOW = 0x00000080,
WS_EX_WINDOWEDGE = 0x00000100,
WS_EX_CLIENTEDGE = 0x00000200,
WS_EX_CONTEXTHELP = 0x00000400,
WS_EX_RIGHT = 0x00001000,
WS_EX_RTLREADING = 0x00002000,
WS_EX_LEFTSCROLLBAR = 0x00004000,
WS_EX_STATICEDGE = 0x00020000,
WS_EX_NOINHERITLAYOUT = 0x00100000, // Disable inheritence of mirroring by children
WS_EX_LAYOUTRTL = 0x00400000, // Right to left mirroring
WS_EX_OVERLAPPEDWINDOW = 0x00000300, // (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE)
WS_EX_CAPTIONOKBTN = 0x80000000,
WS_EX_NODRAG = 0x40000000,
WS_EX_ABOVESTARTUP = 0x20000000,
WS_EX_INK = 0x10000000,
WS_EX_NOANIMATION = 0x04000000,
}
...
[DllImport("coredll.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
enum SWP{
SWP_ASYNCWINDOWPOS = 0x4000,
SWP_DEFERERASE = 0x2000,
SWP_DRAWFRAME = 0x0020,
SWP_FRAMECHANGED = 0x0020,
SWP_HIDEWINDOW = 0x0080,
SWP_NOACTIVATE = 0x0010,
SWP_NOCOPYBITS = 0x0100,
SWP_NOMOVE = 0x0002,
SWP_NOOWNERZORDER = 0x0200,
SWP_NOREDRAW = 0x0008,
SWP_NOREPOSITION = 0x0200,
SWP_NOSENDCHANGING = 0x0400,
SWP_NOSIZE = 0x0001,
SWP_NOZORDER = 0x0004,
SWP_SHOWWINDOW = 0x0040,
}
enum HWNDPOS{
HWND_TOP = 0,
HWND_BOTTOM = 1,
HWND_TOPMOST = -1,
HWND_NOTOPMOST = -2,
}
}
}
希望 stackoverflow 在不久的将来能够上传代码。
问候
约瑟夫
不能在 Windows Mobile 的屏幕上移动表单。他们也不能只占据屏幕的一部分。这只能在 Windows CE 中实现。