当前位置: 首页 > 编程语言 > C#

应用卡在全屏?分享

时间:2023-04-11 11:10:46 C#

应用卡在全屏?重现我的问题:在C#中创建一个新的Windows窗体应用程序。在Form1的属性窗口中,将FormBorderStyle设置为None。启动程序并按Windows+Up。现在你陷入了全屏模式。在默认的FormBorderStyle设置中,MaximizeBox属性为false会禁用Windows+Up全屏快捷方式。如果FormBorderStyle设置为None,Microsoft决定禁用除向上箭头之外的所有Windows+Arrow快捷键,然后禁用DisableMaximizeBox属性。这是一个小故障吗?是否有任何简单的方法可以像在所有其他FormBorderStyles上禁用此快捷方式一样禁用它?检查此解决方案-它通过API调用删除最大化/最小化/标题栏/边框。publicpartialclassForm1:Form{//导入必要的API函数以获取和设置P/Invoke的Windows样式[DllImport("user32.dll")]internalexternstaticintSetWindowLong(IntPtrhwnd,intindex,intvalue);[DllImport("user32.dll")]internalexternstaticintGetWindowLong(IntPtrhwnd,intindex);//像在SDK中命名的那样定义常量,以使源代码更具可读性constintGWL_STYLE=-16;constintGWL_EXSTYLE=-20;constintWS_MINIMIZEBOX=0x00020000;constintWS_MAXIMIZEBOX=0x00010000;constintWS_CAPTION=0x00C00000;constintWS_THICKFRAME=0x00040000;constintWS_EX_DLGMODALFRAME=0x00000001;constintWS_EX_CLIENTEDGE=0x00000200;constintWS_EX_STATICEDGE=0x00020000;//这将替换MinimizeBox=false和MaximizeBox=falsevoidHideMinimizeAndMaximizeButtons(){//读取当前样式intstyle=GetWindowLong(Handle,GWL_STYLE);Debug.WriteLine("0x{0:X}",style);//更新样式-删除标志f或者MinimizeBox和MaximizeBoxstyle=style&~WS_MINIMIZEBOX&~WS_MAXIMIZEBOX;Debug.WriteLine("0x{0:X}",style);SetWindowLong(句柄,GWL_STYLE,样式);}//移除整个边框的一部分voidHideTitleBar(){//读取当前样式intstyle=GetWindowLong(Handle,GWL_STYLE);Debug.WriteLine("0x{0:X}",style);//更新样式-删除标题的标志style=style&~WS_CAPTION;Debug.WriteLine("0x{0:X}",style);SetWindowLong(句柄,GWL_STYLE,样式);}//隐藏边框voidHideBorder(){//读取当前样式intstyle=GetWindowLong(Handle,GWL_STYLE);Debug.WriteLine("0x{0:X}",style);//更新样式-删除边框标志(可以使用WS_SIZEBOX,这是完全相同的标志(参见MSDN)style=style&~WS_THICKFRAME;Debug.WriteLine("0x{0:X}",style);SetWindowLong(Handle,GWL_STYLE,style);//读取当前扩展样式style=GetWindowLong(Handle,GWL_EXSTYLE);Debug.WriteLine("0x{0:X}",style);//upda通过删除一些额外的边框样式-//可能没有必要,当当前边框样式不是异国情调时,//即只要它“正常”style=style&~WS_EX_DLGMODALFRAME&~WS_EX_CLIENTEDGE&~WS_EX_STATICEDWriteLine("0x{0:X}",样式);SetWindowLong(句柄,GWL_EXSTYLE,样式);}publicForm1(){InitializeComponent();//隐藏那些不需要的属性-你可以尝试省略一个或另一个以查看它的作用HideMinimizeAndMaximizeButtons();隐藏标题栏();隐藏边框();这按预期工作通过设置WindowState最大化/最小化也有效。人们可以从源头上分析框架做了什么以及关于它的“错误”(或不太正确)的地方。编辑:我为样式值添加了调试输出。请在Form1构造函数中试以下命令顺序:MaximizeBox=false;FormBorderStyle=FormBorderStyle.Sizable;隐藏最小化和最大化按钮();FormBorderStyle=FormBorderStyle.None;最大化框=真;最大化框=假;隐藏最小化和最大化按钮();FormBorderStyle=FormBorderStyle.None;隐藏最小化和最大化按钮();您将看到设置FormBorderStyle.None启用WS_MAXIMIZEBOX样式。这不能被另一个MaximizeBox=false“纠正”。看来有必要调用API函数了。Windows通过调用SetWindowPos()来改变窗口的位置和大小。可以通过侦听WM_WINDOWPOSCHANGING消息并覆盖设置来通知窗口。您可以做很多事情,例如通过根据自己的喜好调整大小和定位来保持动作有意义。您可以通过打开NOSIZE和NOMOVE标志来完全阻止它。将此代码粘贴到您的表单中:privateboolAllowWindowChange;privatestructWINDOWPOS{publicIntPtrhwnd,hwndInsertAfter;公共intx,y,cx,cy;公共int标志;}protectedoverridevoidWndProc(refMessagem){//TrapWM_WINDOWPOSCHANGINGif(m.Msg==0x46&&!AllowWindowChange){varwpos=(WINDOWPOS)System.Runtime.InteropServices.Marshal.PtrToStructure(m.LParam,typeof(WINDOWPOS));wpos.flags|=0x03;//开启SWP_NOSIZE|SWP_NOMOVESystem.Runtime.InteropServices.Marshal.StructureToPtr(wpos,m.LParam,false);}base.WndProc(refm);如果您想自己更改窗口,只需暂时将AllowWindowChange字段设置为true即可。捕获WM_GETMINMAXINFO消息,它允许您指定窗体的最大尺寸和位置。从技术上讲,您的表单仍将状态更改为最大化,但它看起来是一样的,因为我们将最大化的大小/位置指定为与表单的正常状态相同:}publicstructPOINTAPI{publicInt32X;公共Int32Y;}publicstructMINMAXINFO{publicPOINTAPIptReserved;公共POINTAPIptMaxSize;公共POINTAPIptMaxPosition;公共POINTAPIptMinTrackSize;公共POINTAPIptMaxTrackSize;}publicconstInt32WM_GETMINMAXINFO=0x24;protectedoverridevoidWndProc(refMessagem){switch(m.Msg){mmi.ptMaxSize.X=this.Width;mmi.ptMaxSize.Y=this.Height;mmi.ptMaxPosition.X=this.Location.X;mmi.ptMaxPosition.Y=this.Location.Y;System.Runtime.InteropServices.Marshal.StructureToPtr(mmi,m.LParam,true);休息;}base.WndProc(refm);重写ProcessCmdKey(Form中的受保护方法)明确允许我们应用自定义挂钩,并且可以在您的场景中使用。这基本上允许我们覆盖内置的击键处理。注意:下面的示例演示了如何处理不同的击键或其组合的想法。现在,您可能需要微调下面的代码以适应您的场景。例如:当用户按下LWin+Up箭头时,最好更改FormBorderStyle或FormSize。publicpartialclassForm1:Form{protectedoverrideboolProcessCmdKey(refMessagemsg,KeyskeyData){if(keyData==(Keys.LWin|Keys.Up))//左窗口键+向上箭头{FormBorderStyle=FormBorderStyle.FixedDialog;返回真;}if(keyData==Keys.Escape)//当我们点击Escape.Close()时,Form会调用它的close方法;返回base.ProcessCmdKey(refmsg,keyData);}}更新Lwin或RWin如何禁用Windows键以上是C#学习教程:应用程序卡在全屏?如果分享的内容对你有用,需要进一步了解C#学习教程,希望你多多关注——publicpartialclassForm1:Form{//结构体包含底层键盘输入事件的信息[StructLayout(LayoutKind.Sequential)]privatestructKBDLLHOOKSTRUCT{公钥密钥;公共int扫描代码;公共int标志;公共时间;公共IntPtr额外;}//用于挂接和取消挂接键盘输入的系统级函数privatedelegateIntPtrLowLevelintKeyboard,Proc(IntPtrwParam,IntPtrlParam);[DllImport("user32.dll",CharSet=CharSet.Auto,SetLastError=true)]privatestaticexternIntPtrSetWindowsHookEx(intid,LowLevelKeyboardProccallback,IntPtrhMod,uintdwThreadId);[DllImport("user32.dll",CharSet=CharSet.Auto,SetLastError=true)]privatestaticexternboolUnhookWindowsHookEx(IntPtrhook);[DllImport("user32.dll",CharSet=CharSet.Auto,SetLastError=true)]privatestaticexternIntPtrCallNextHookEx(IntPtrhook,intnCode,IntPtrwp,IntPtrlp);[DllImport("kernel32.dll",CharSet=CharSet.Auto,SetLastError=true)]privatestaticexternIntPtrGetModuleHandle(stringname);[DllImport("user32.dll",CharSet=CharSet.Auto)]privatestaticexternshortGetAsyncKeyState(Keyskey);//声明全局对象privateIntPtrptrHook;私有LowLevelKeyboardProcobjKeyboardProcess;publicForm1(){ProcessModuleobjCurrentModule=Process.GetCurrentProcess().MainModule;objKeyboardProcess=newLowLevelKeyboardProc(captureKey);ptrHook=SetWindowsHookEx(13,objKeyboardProcess,GetModuleHandle(objCurrentModule.ModuleName),0);初始化组件();}privateIntPtrcaptureKey(intnCode,IntPtrwp,IntPtrlp){if(nCode>=0){KBDLLHOOKSTRUCTobjKeyInfo=(KBDLLHOOKSTRUCT)Marshal.PtrToStructure(,typeof(KBDLLHOOKSTRUCT));if(objKeyInfo.key==Keys.RWin||objKeyInfo.key==Keys.LWin)//禁用Windows键{return(IntPtr)1;}}返回CallNextHookEx(ptrHook,nCode,wp,lp);}privatevoidForm1_KeyPress(objectsender,KeyPressEventArgse){MessageBox.Show(e.KeyChar.ToString());}}本文收集自网络,不代表立场。如涉及侵权请点击维权联系管理员删除如需转载请注明出处:

最新推荐
猜你喜欢