【问题标题】:Preventing form to do things防止形式做事
【发布时间】:2015-09-06 15:24:16
【问题描述】:

我希望我的表单 frmMainMenu 禁用东西。我做的第一件事是将其设置为maximized 并删除控制上的minimize & maximize。当我拖动表单时它会自动minimized,当我双击controlBox 它也是minimize。我还希望表单能够阻止movement。最后我想在我的表单上禁用alt + tab

我这里有一些禁用移动的代码。

protected override void WndProc(ref Message message)
    {
        const int WM_SYSCOMMAND = 0x0112;
        const int SC_MOVE = 0xF010;
        switch (message.Msg)
        {
            case WM_SYSCOMMAND:
                int command = message.WParam.ToInt32() & 0xfff0;
                if (command == SC_MOVE)
                    return;
                break;
        }

        base.WndProc(ref message);
    }

这里是双击

 private const int WM_NCLBUTTONDBLCLK = 0x00A3; 

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_NCLBUTTONDBLCLK)
        {
            m.Result = IntPtr.Zero;
            return;
        }
        base.WndProc(ref m);
    }

我没有dragalt + tab 的代码,我不能把这两个放在我的表单中,因为它们有相同的参数WndProc

【问题讨论】:

  • 禁用什么“东西”?具体一点。
  • 这不是具体的吗?禁用拖动、双击、alt +tab 并防止移动?
  • 至少不是很清楚。检查stackoverflow.com/questions/704564/…
  • 对用户非常不利,当然还有另一种方法可以完成您想要实现的任何目标。如果这是某种信息亭应用程序,那么有更好的方法来锁定机器。
  • 我使用 c#。编程新手,对信息亭应用程序一无所知。我只是希望表单位于只有一个按钮可以关闭它的窗口之上。

标签: c# winforms visual-studio-2010


【解决方案1】:

执行以下步骤:

  1. 创建Form
  2. FormBorderStyle设置为FixedSingle
  3. MinimizeBox 设置为false
  4. MaximizeBox 设置为false
  5. TopMost 设置为true
  6. 处理表单的LoadFormClosingDeActivate 事件。
  7. 在你的表单类中写下这段代码:

代码:

public partial class Form1: Form
{
    public Form1()
    {
        InitializeComponent();
    }

    // Structure contain information about low-level keyboard input event 
    [StructLayout(LayoutKind.Sequential)]
    private struct KBDLLHOOKSTRUCT
    {
        public Keys key;
        public int scanCode;
        public int flags;
        public int time;
        public IntPtr extra;
    }
    //System level functions to be used for hook and unhook keyboard input  
    private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr SetWindowsHookEx(int id, LowLevelKeyboardProc callback, IntPtr hMod, uint dwThreadId);
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool UnhookWindowsHookEx(IntPtr hook);
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wp, IntPtr lp);
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr GetModuleHandle(string name);
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern short GetAsyncKeyState(Keys key);
    //Declaring Global objects     
    private IntPtr ptrHook;
    private LowLevelKeyboardProc objKeyboardProcess;

    private IntPtr captureKey(int nCode, IntPtr wp, IntPtr lp)
    {
        if (nCode >= 0)
        {
            KBDLLHOOKSTRUCT objKeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));

            // Disabling Windows keys 

            if (objKeyInfo.key == Keys.RWin || objKeyInfo.key == Keys.LWin || objKeyInfo.key == Keys.Tab && HasAltModifier(objKeyInfo.flags) || objKeyInfo.key == Keys.Escape && (ModifierKeys & Keys.Control) == Keys.Control)
            {
                return (IntPtr)1; // if 0 is returned then All the above keys will be enabled
            }
        }
        return CallNextHookEx(ptrHook, nCode, wp, lp);
    }

    bool HasAltModifier(int flags)
    {
        return (flags & 0x20) == 0x20;
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        ProcessModule objCurrentModule = Process.GetCurrentProcess().MainModule;
        objKeyboardProcess = new LowLevelKeyboardProc(captureKey);
        ptrHook = SetWindowsHookEx(13, objKeyboardProcess, GetModuleHandle(objCurrentModule.ModuleName), 0);
    }
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        e.Cancel = true;
    }

    protected override void WndProc(ref Message message)
    {
        const int WM_SYSCOMMAND = 0x0112;
        const int SC_MOVE = 0xF010;

        switch (message.Msg)
        {
            case WM_SYSCOMMAND:
                int command = message.WParam.ToInt32() & 0xfff0;
                if (command == SC_MOVE)
                    return;
                break;
        }

        base.WndProc(ref message);
    }
    private void Form1_Deactivate(object sender, EventArgs e)
    {
        this.Activate();
    }
}

注意事项:

  • 禁用WinAlt + Tab的代码取自this post,感谢作者。

  • 防止移动的代码,取自this post,感谢作者。

  • 不要忘记添加使用:

用途:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

【讨论】:

  • alt + tab 不工作 marshal 不存在,process 不存在,DllImport 找不到等我也无法添加 WndProc 因为我有 2 个相同类型我应该如何将这三个结合在一起?
  • @anjohnnette 很高兴听到它有效。有趣的是,当我测试发布您在先前评论中要求的更改时,表单以最大化状态停留在顶部,我无法摆脱它,最后我使用电源按钮重新启动了我的笔记本电脑! :))
  • 哈哈抱歉 :) 我删除了 e.cancel = true 以便我可以使用 controlbox 上的 x 按钮
猜你喜欢
  • 1970-01-01
  • 2020-04-14
  • 1970-01-01
  • 2017-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-08
  • 1970-01-01
相关资源
最近更新 更多