Eli의 여백

바쁜 나날들 사이에서 생각났던 이런저런 것들을 적어봅니다.

프로그래밍

C# 앱 제작시 Topmost 적용 안되는 현상 해결방법

Eli♪ 2024. 6. 12. 02:01

문제상황

게임화면 위에 원하는 미니맵을 띄우고 싶어서 개발을 시작함. VS써서 C#으로 Windows Forms app을 만들었으나 Forms.TopMost = true가 제대로 먹히지 않아 게임화면 밑으로 앱이 자꾸 묻힘. 인터넷 찾아보니 TopMost나 TopLevel에 parent 지정하는 것으로 z순서를 지정하라는데 내가 원하는 건 다른 앱 위에 올리는거라 결국엔 안됐음. 이전에 win32api 할 때 SetWindowEx로 임의의 창을 강제로 always on top으로 올리는 기능이 가능했기 때문에 c#에서도 분명히 될거라고 생각했음.

 

해결방법

결국은 user32.dll을 P/invoke로 import해서 해결 가능했다. 코드는 다음과 같다.

using System.ComponentModel;
using System.Runtime.InteropServices;

namespace TW_Maps
{
    partial class TopModal
    {
        private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
        private const UInt32 SWP_NOSIZE = 0x0001;
        private const UInt32 SWP_NOMOVE = 0x0002;
        private const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

        /* Some codes */

        private void InitializeComponent()
        {
            SuspendLayout();

            /* Some codes */

            SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
        }
    }
}

 

적용결과

아래와 같이 게임화면 위로 잘 올라왔다.

 

결과물

다음의 링크에 결과물 업로드해 두었다. MIT 라이센스로 배포하였다.

항상 위 기능 외에도 snap to screen edge라든가 draggable borderless window라든가 하는 잡기술들이 들어가 있다.

https://github.com/ProjectEli/TW_Maps/releases/latest

 

Release v1.1 항상 위 기능 제대로 적용 · ProjectEli/TW_Maps

사용법 테일즈위버 쟁탈전용 미니맵입니다. 파일을 실행하면 블랙홀맵이 나옵니다. 미니맵은 드래그 가능하고, 1~5 단축키를 사용하여 크기 조절 가능합니다. 미니맵을 화면 가장자리 근처로 놓

github.com