2009-12-08 5 views
0

Я пишу .Net COM DLL, которая запускается внутри собственного приложения Windows.C#: Получение ярлыка, введенного в панель состояния сотового приложения, для отображения

Я пытаюсь добавить дополнительную панель в панель состояния приложения, и у нее нет какой-либо конкретной реализации, поэтому я пытаюсь подклассифицировать панель состояния приложения самостоятельно.

Я использую API-интерфейс Win32 SetParent() для переключения родителя элемента управления меткой из формы .Net в экземпляр msctls_statusbar32. Я использовал ярлык, потому что это ближайшая реализация для собственного «статического» класса, который я мог бы найти, не нажимая собственный контроль.

Как-то мне даже удалось заставить NativeWindow успешно подключиться к сообщениям о статусе и сообщениях моего лейбла (хотя в данный момент он просто передает их всем следующему WndProc), и я назначил соответствующие стили и стилиExs к окну моего ярлыка, и я вижу свою метку в качестве дочернего элемента с msctls_statusbar32 в качестве родителя. Все выглядит, как будто он должен работать правильно, но это не так. Мой элемент управления не отображается в строке состояния родительского приложения.

Я не понимаю, почему он не появляется. Почти все, что я могу думать о совпадениях правильно - предоставлено, класс для моего ярлыка - «WindowsForms10.STATIC.app.0.378734a», а не «статический», но кроме того, что он находится на правильном процессе и потоке, имеет соответствующее окно стилей (по крайней мере, шестнадцатеричное значение ... Spy ++, похоже, перечислит их по-разному), и для всех целей довольно много сочетается с остальными элементами управления. Кто-нибудь знает, что еще нужно сделать, чтобы это было видно?

(Первоначально я отправился по пути CreateWindowEx и установил обратные вызовы WNDPROC, но я не смог заставить приложение работать ... он замерзнет на минуту или около того, а затем разморозит, и я заметил бы, что мое окно исчезло из дерево окна)

спасибо!

+0

Почему вы не можете использовать существующий API-интерфейс статусов для добавления панелей и установки их текста? –

+0

Я, наконец, выкопал правильные документы для statusbar32 api (никогда не работал с этим материалом раньше ...), и сейчас я планирую вставить панель, нарисованную владельцем, где-то внутри. –

+0

Почему владелец рисует, если это всего лишь текст? –

ответ

0

Как выясняется, ответ был прост dumbfoundingly ... X лейбла и Y Coords были из области отображения STATUSBAR родителя. Перемещение их на (0, 0), и оно появляется прямо там! Конечно, теперь проблемы перешли к: C# WinForms control in .Net COM Server won't redraw

0

Многие возможные причины:

  1. управления Ярлык .Net взрывает, когда он считает это не имеет родителя WinForms.
  2. Собственная строка состояния рисует элемент управления ярлыками из-за неправильного Z-ордера.
  3. Элемент управления Label не отображается.
2

вы можете попробовать работать с существующим контролем состояния; что вы можете сделать, это сбросить текст в существующий раздел или добавить новый; также вам, вероятно, потребуется установить новые ширины в существующие разделы панели состояния. Вы можете найти информацию о том, как работать с элементом управления статусом здесь: msdn Status Bars

Пожалуйста, найдите пример того, как вы могли бы сделать это ниже. Я на самом деле пробовал его с помощью объекта C# com, используемого приложением win32, и, похоже, он работает отлично.

[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(); 
    } 

надеюсь, что это помогает, считает