Adobe Acrobat Reader 의 확장자 연결 기능 구현 방법 문의

Adobe Acrobat Reader 를 설치하고 난 후
.pdf 확장자의 연결 프로그램을 설정하는 화면에서
아래 그림과 같이 시각적인 가이드를 제공하여 만족스러웠던 경험이 있습니다.

제가 Winform 프로그램을 제작하면서 이런 기능을 추가하고 싶은데
어떤 방법을 사용해야 구현이 가능할지 감이 잡히지 않아 도움을 요청 드립니다.

  1. 그림에서와 같이 특정 파일 형식(.pdf 등) 의 속성창을 C#에서 어떻게 호출 할 수 있을까요?
  2. 속성창을 강조하기 위해 속성 창 외 나머지 부분을 흐리게 처리하려면 어떻게 해야 할까요?
  3. 특정 버튼 위치에 그림과 같은 가이드 메세지를 표시하려면 어떻게 해야 할까요?

해당 기능 구현 시 추가적으로 고려해야 할 사항은
속성 창의 위치가 고정적이지 않을 것이라는 점 과
속성 창이 닫히면 2,3번의 기능을 초기화 해야 한다는 점 입니다.

조언 부탁드립니다.

감사합니다.

image

  1. Stack Overflow 답변 .net - How do I display a file's Properties dialog from C#? - Stack Overflow
using System.Runtime.InteropServices;

[DllImport("shell32.dll", CharSet = CharSet.Auto)]
static extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SHELLEXECUTEINFO
{
    public int cbSize;
    public uint fMask;
    public IntPtr hwnd;
    [MarshalAs(UnmanagedType.LPTStr)]
    public string lpVerb;
    [MarshalAs(UnmanagedType.LPTStr)]
    public string lpFile;
    [MarshalAs(UnmanagedType.LPTStr)]
    public string lpParameters;
    [MarshalAs(UnmanagedType.LPTStr)]
    public string lpDirectory;
    public int nShow;
    public IntPtr hInstApp;
    public IntPtr lpIDList;
    [MarshalAs(UnmanagedType.LPTStr)]
    public string lpClass;
    public IntPtr hkeyClass;
    public uint dwHotKey;
    public IntPtr hIcon;
    public IntPtr hProcess;
}

private const int SW_SHOW = 5;
private const uint SEE_MASK_INVOKEIDLIST = 12;
public static bool ShowFileProperties(string Filename)
{
    SHELLEXECUTEINFO info = new SHELLEXECUTEINFO();
    info.cbSize = Marshal.SizeOf(info);
    info.lpVerb = "properties";
    info.lpFile = Filename;
    info.nShow = SW_SHOW;
    info.fMask = SEE_MASK_INVOKEIDLIST;
    return ShellExecuteEx(ref info);        
}

// button click
private void button1_Click(object sender, EventArgs e)
{
    string path = @"C:\Users\test\Documents\test.text";
    ShowFileProperties(path);
}
  1. 전체 화면 크기를 커버하는 Borderless Form을 만들고 Opacity 값을 주면 될 듯 하네요.
this.Opacity = 0.5;
this.ControlBox = false;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.FormBorderStyle = FormBorderStyle.None;
this.WindowState = FormWindowState.Maximized;

그리고 속성 창의 핸들을 알아내신 뒤 WIN32 API SetWindowPos ([WinAPI] SetWindowPos (tistory.com))를 이용해서 흐림 효과를 보여주는 Form을 속성 창 뒤로 보낼 수 있습니다.
그 이전에 속성 창을 SetWindowPos 함수에 HWND_TOPMOST를 넣고 호출해서 최상위 창으로 만든 뒤 처리하셔야 할 것 같네요.

  1. 2.에서 속성 창의 핸들을 알아내셨다면 WIN32 API GetWindowRect 함수를 통해 속성 창의 위치와 크기를 알아내실 수 있습니다. (그림자 처리 필요 시)
    그리고 WIN32 API FindWindow 함수([C#] FindWindow(), FindWindowEx()를 이용한 윈도우 창 찾기 (tistory.com))를 사용하시면 해당 버튼의 위치를 가져올 수 있습니다. (속성 창의 핸들을 알아내려면 이 함수를 쓰셔야 합니다.)
    image

고려사항은 타이머를 짧은 주기(50ms 정도)로 돌려셔 속성 창의 위치와 버튼의 위치를 확인해서 업데이트 하시면 되고 GetWindowRect 함수의 리턴값이 false이면 창이 닫혔다고 판단하면 될 듯합니다.

4개의 좋아요

정말 강추이십니다 이런 정성을 들여서 답변을 하시다니!!!
후킹으로 이벤트 잡아서 좌표에다가 뭐 뛰우고 이걸
백그라운드 작업 거는것 시간이 많이 드셨을텐데요

1개의 좋아요

:+1: :+1: :+1: :+1: :+1:

정성스러운 답변 감사드립니다!! 참고해서 작업해볼게요~

1개의 좋아요