0

我正在为 windows mobile 6.5(c#、.net、compact 框架)开发一个应用程序,我很难找到如何在不使用默认滚动条的情况下上下拖动我的表单。我的表单比设备的屏幕大,我不希望用户使用默认滚动条,而是拖动表单。

关于如何做到这一点的任何想法?

谢谢

4

2 回答 2

1

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 在不久的将来能够上传代码。

问候

约瑟夫

于 2012-10-30T14:34:52.347 回答
0

不能在 Windows Mobile 的屏幕上移动表单。他们也不能只占据屏幕的一部分。这只能在 Windows CE 中实现。

于 2012-10-29T12:29:51.973 回答