2009-12-08 4 views
0

네이티브 Windows 응용 프로그램 내에서 실행되는 .NET COM DLL을 작성하고 있습니다.C# : 네이티브 앱의 상태 표시 줄에 레이블을 삽입하여 표시

이 응용 프로그램의 상태 표시 줄에 추가 창을 삽입하려고하는데 특정 구현이 없으므로 응용 프로그램의 상태 표시 줄을 직접 하위 클래스로 만들려고합니다.

레이블 컨트롤의 부모를 .NET 폼에서 msctls_statusbar32 인스턴스로 전환하려면 Win32 API SetParent()를 사용하고 있습니다. 내 자신의 컨트롤을 작성하지 않고 찾을 수있는 네이티브 "정적"클래스 컨트롤에 가장 가까운 구현이기 때문에 레이블을 사용했습니다.

어떻게 든 NativeWindow를 성공적으로 상태 표시 줄과 내 레이블의 메시지에 모두 연결할 수있었습니다. (하지만 지금은 다음 WndProc에 모두 전달됩니다.) 일치하는 스타일과 styleExs를 할당했습니다. 내 레이블의 창으로 이동하면 msctls_statusbar32를 부모로 사용하여 내 레이블을 자식으로 볼 수 있습니다. 모든게 은 제대로 작동해야합니다.처럼 보이지만 그렇지는 않습니다. 내 컨트롤이 상위 앱의 상태 표시 줄에 표시되지 않습니다.

내가 이해가 가지 않는 이유는 그것이 나타나지 않는 이유입니다. 거의 모든 것이 일치한다고 생각할 수있는 거의 모든 것 - 부여 된 클래스의 레이블은 "WindowsForms10.STATIC.app.0.378734a"이며 "정적"이 아니라 올바른 프로세스 및 스레드에있는 것 외에 일치하는 창을가집니다. 스타일 (적어도 16 진수 값 ... 스파이 ++는 다르게 열거하는 것처럼 보입니다.), 모든 목적으로 나머지 컨트롤과 꽤 잘 어울립니다. 아무도 그것을 볼 수있게하기 위해해야 ​​할 일이 무엇인지 알지 못합니까?

(원래 CreateWindowEx의 경로를 빠져 나와 WNDPROC 콜백을 설정했지만 작동하도록 앱을 가져올 수 없었습니다 ... 잠시 멈추고 고정 해제하고 내 창이 사라진 것을 눈치 챘을 것입니다. 창문 트리)

고마워요!

+0

기존 상태 표시 줄 API를 사용하여 창을 추가하고 텍스트를 설정할 수없는 이유는 무엇입니까? –

+0

나는 마침내 statusbar32 API에 대한 올바른 문서를 파헤 쳤다. (이전에는이 ​​작업을하지 않았다 ...) 내 계획은 지금 어딘가에 소유자가 그린 창을 삽입하는 것이다. –

+0

그냥 텍스트 인 경우 왜 소유자가 그립니다? –

답변

0

많은 가능한 이유 : 그것은 윈폼 부모가없는 발견하면

  1. 닷넷 Label 컨트롤이 불면.
  2. 올바르지 않은 Z- 순서로 인해 기본 상태 표시 줄이 레이블 컨트롤을 그립니다.
  3. 레이블 컨트롤이 표시되지 않습니다.
2

기존 상태 표시 줄 컨트롤로 작업 해 볼 수 있습니다. 할 수있는 일은 텍스트를 기존 섹션으로 재설정하거나 새 섹션을 추가하는 것입니다. 또한 상태 막대의 기존 섹션에 새로운 너비를 설정해야 할 수도 있습니다. 여기에서 상태 표시 줄 컨트롤 사용 방법에 대한 자세한 내용을 확인할 수 있습니다. msdn Status Bars

아래에서 어떻게 할 수 있는지 예제를 참조하십시오. 사실은 Win32 응용 프로그램에서 사용되는 C# com 객체로 시도했지만 제대로 작동하는 것 같습니다. 이 레이블의 X 및 Y 좌표가 상태 표시 부모의 디스플레이 영역에서 있었다 ... 대답은 dumbfoundingly 간단 나오는 것에 따라이 도움이

[ComVisible(true)] 
    [Guid("CC5B405F-F3CD-417E-AA00-4638A12A2E94"), 
    ClassInterface(ClassInterfaceType.None)] 
    public class TestInterface : ITestInterface // see declaration of the interface below 
    { 
     [DllImport("user32.dll", SetLastError = true)] 
     public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle); 

     [DllImport("user32.dll", CharSet = CharSet.Auto)] 
     static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, IntPtr lParam); 

     public const int SB_SETTEXT = 1035; 
     public const int SB_SETPARTS = 1028; 
     public const int SB_GETPARTS = 1030; 

     public unsafe void Test() 
     { 
      IntPtr mainWindowHandle = Process.GetCurrentProcess().MainWindowHandle; 
      // find status bar control on the main window of the application 
      IntPtr statusBarHandle = FindWindowEx(mainWindowHandle, IntPtr.Zero, "msctls_statusbar32", IntPtr.Zero); 
      if (statusBarHandle != IntPtr.Zero) 
      { 
       // set text for the existing part with index 0 
       IntPtr text = Marshal.StringToHGlobalAuto("test text 0"); 
       SendMessage(statusBarHandle, SB_SETTEXT, 0, text); 
       Marshal.FreeHGlobal(text); 

       // create new parts width array 
       int nParts = SendMessage(statusBarHandle, SB_GETPARTS, 0, IntPtr.Zero).ToInt32(); 
       nParts++; 
       IntPtr memPtr = Marshal.AllocHGlobal(sizeof(int) * nParts); 
       int partWidth = 100; // set parts width according to the form size 
       for (int i = 0; i < nParts; i++) 
       { 
        Marshal.WriteInt32(memPtr, i*sizeof(int), partWidth); 
        partWidth += partWidth; 
       } 
       SendMessage(statusBarHandle, SB_SETPARTS, nParts, memPtr); 
       Marshal.FreeHGlobal(memPtr); 

       // set text for the new part 
       IntPtr text0 = Marshal.StringToHGlobalAuto("new section text 1"); 
       SendMessage(statusBarHandle, SB_SETTEXT, nParts-1, text0); 
       Marshal.FreeHGlobal(text0); 
      } 
     } 
    } 

    [ComVisible(true)] 
    [Guid("694C1820-04B6-4988-928F-FD858B95C880")] 
    public interface ITestInterface 
    { 
     [DispId(1)] 
     void Test(); 
    } 

희망,

관련 문제