0

Within each tab, the control centers the icon and label, placing the icon to the left of the label. In WinApi you can force the icon to the left, leaving the label centered, by specifying the TCS_FORCEICONLEFT style. You can left-align both the icon and label by using the TCS_FORCELABELLEFT style.

How can I make the same in c#? There is similar question, but those solution does not work for me, despyte I use Edward's advice. In class derived from TabControl (I need draggable tabs, but now while tab is dragged the alignment of its label breaks since I set the SizeMode to Fixed to get tabs the same width and properly dragging):

[DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]
protected static extern bool SetWindowLong32(IntPtr ptr, int index, int value);
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)]
protected static extern bool SetWindowLongPtr64(IntPtr ptr, int index, int value);
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
protected static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);

private const int GWL_STYLE = -16;
private const int TCS_FORCELABELLEFT = 0x20;
protected static bool SetWindowLong(IntPtr ptr, int index, int value)
{
     if (IntPtr.Size == 4)
     {
         return SetWindowLong32(ptr, index, value);
     }
     return SetWindowLongPtr64(ptr, index, value);
}

and in TabControl constructor:

SetWindowLong(Handle, GWL_STYLE, TCS_FORCELABELLEFT);
var SWP_FRAMECHANGED = 0x20;
var SWP_NOMOVE = 0x2;
var SWP_NOSIZE = 0x1;
var SWP_NOZORDER = 0x4;
SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);

I'm aware it's possible use owner-drawn mode, but I don't know how can i use the system style changing only necessary elements.

Community
  • 1
  • 1
SerG
  • 1,251
  • 4
  • 18
  • 37

1 Answers1

0

If you want to just call SetWindowLong, try

[DllImport("user32.dll")]
static extern bool SetWindowLong(IntPtr ptr, int index, int value);

If you are targeting 32-/64-bit platforms, this SO answer might throw some light on how to invoke the function properly.

Community
  • 1
  • 1
Edward Clements
  • 5,040
  • 2
  • 21
  • 27
  • Now I have no error, but labels still have alignment by center. – SerG Aug 15 '13 at 10:03
  • [MSDN Doc](http://msdn.microsoft.com/en-us/library/windows/desktop/ms633591(v=vs.85).aspx) for `SetWindowLong` says "Certain window data is cached, so changes you make using SetWindowLong will not take effect until you call the [SetWindowPos](http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545(v=vs.85).aspx) function" -- the docs also say to use `SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED` for `uFlags` – Edward Clements Aug 15 '13 at 11:42
  • I saw in your edit that you are calling the functions `in TabControl constructor` -- with the normal API, the control is not created until after the constructor, could you move the calls to after the constructor? does `Handle` contain a valid windows handle? – Edward Clements Aug 15 '13 at 13:45
  • I have moved it with no result. I think the handle is valid because when I accidentally pass main window handle it becomes fullscreen also SetWindowLong returns true. – SerG Aug 15 '13 at 13:57
  • I think there's a misunderstanding, I meant the handle of the tab control that you are using in the calls to `SetWindowLong` and `SetWindowPos` -- could you post more code of the control creation and the two calls to SetWindow*? – Edward Clements Aug 15 '13 at 14:42
  • I also meant that tabControl handle was valid. Code of the two calls is already posted (and I tried place it into both constructors: form or TabControl). Control creation is usual as standard TabControl (generated automatically, I've only changed the class name). – SerG Aug 15 '13 at 15:53