|
Very nice control - thank you!
I will study it, because I am very new in programming own controls AND I could need this in my own project.
I have a suggestion:
What about including an "x", to close the tabs. This could be helpful, if you are using the tabs for files.
I could imagine 2 different ways - an "x" for every single tabpage ( I would prefer that) or an "x" on the right side of the whole tab-control, closing the active tab.
Is this possible to include?
Hope to read you soon
T_uRRiCA_N
|
|
|
|
|
I'm glad you like it, but what you asking for is a topic of another article. It's quite rare thing to see standard tabs with close buttons. Mostly, custom tabs are used (just a few examples - Visual Studio, Firefox, Safari, Internet Explorer, etc). My purpose was to do Microsoft's job and control is oriented strictly to that. In fact, they should have done it, but they didn't. For them it would be easy (just some additional bitmaps inside theme file + some additional code to load them instead of top ones).
|
|
|
|
|
I understand his request. He is supposed to use this control to make a pseudo-MDI application window.
If you can help implement this feature, I think quite some programmers can benefit from it.
|
|
|
|
|
Hello,
first -> thanks for this article and your control.
second -> is there a way that you implement the right and the left places for the tabs?
BTW the property: Alignment shows the options to place the tabs right or left but they are ignored.
Regards
Tim
|
|
|
|
|
Yes, these options persist, because the property is inherited from parent control. Ignore is implemented specially, because if I remove it you will see very ugly appearance by MS. Adding right or left tabs is possible but it's required to perform some additional tricks with bitmap rotation(and I guess we can't escape exotic look of tab scroller). But I dislike side tabs just because they are very inconvenient to read as they are. The solution is to implement them with normal horizontal text like it's done in WPF. But I think in this case it'll be required to overwrite control from scratch.
|
|
|
|
|
Hi, I would like to implement the tab control for left and right tabs, too. But I am completely lost as where to begin. As I examine the codes written and the comments most of you put, it seems that most of you are quite knowledgeable in the .NET framework especially in term of how the Windows Forms is constructed. As for myself, I don't understand most of what you guys discussed. I only understand the basics of using Windows Forms in design mode and programming components with certain functionality. Looking at these codes, I don't know what majority of the statements, libraries, or types mean. May anyone of you guide me in term of what to read or do in order to be able to implement the left and right tab control?
|
|
|
|
|
Hi, it looks like you are newbie in that. So I'll tell you how Windows Forms constructed: they are just wrappers for native Win32 controls. And therefore you can perform with them almost all the tricks that are applicable to native windows. Some things you can do via .NET, but other portion can be done only by using Win32 API via platform interoperability. So you must have some knowledge in Win32 programming using only old good plain C language. You have to know what are windows, how do they interact with each other, what is window procedure, what is message queue, how to process message and so on... Also you need some knowledges in GDI and GDI+. Oh, I feel like a dinosaur with all that stuff I see you're from USA, so I can't recommend some book in English for you. As for myself, I learned basics years ago in one Russian book that was called (direct translation) "Programming MFC, 2nd edition" or something like that. Then it was practice and MSDN reading.
So, if you still wanna do it, prepare for tough job.
|
|
|
|
|
Thanks...it does seem a long way...luckily, I have a good foundation (B.S. Computer Engineering) to start from. Just curious, you seem very knowledgeable in software. I have two questions for you.
With what you currently know, do you put much less effort than before on your continued learning for software? Because from my standpoint, it seems like a long and endless learning path for software, let alone for hardware. From the beginning, software was so simple then. But now, it expands into many different divisions: operating system, graphic designs, embedded software, firmware, database, compiler, web development, etc. Each of which is like another field.
The second question is quite related to the first one. Do you, at certain time, feel overwhelmed with what you need to know?
|
|
|
|
|
You know, programming is constant self-improving by definition if you wanna be hot and stay in touch. Just because technologies are progressing so fast. Back in 2003 I used 3.5" diskettes and it was OK, but they became sh*t in 2005 .
My answer for your first question is: yes, not much less but less. Because technologies are sometimes similar to each other and every new one is often derived from old one, so if you know old one it won't be such a tough task for you. Windows Forms is an example. As I told you, they are based on native Win32 windows, so if you were a guru in native UI programming you need only shallow look to understand. But do you remember my first statement? Programming job is a constant self-improving... So, of course I have to learn some new stuff periodically.
Second answer: yes, there are times Especially when a technology is not so obvious or I have very poor documentation and I need to guess, what happens if I do so.
|
|
|
|
|
Thanks for that nice control, but there is a bug. I use it with tabs on top, and the font "Arial", bold, size 11 pt, for the tabs titles ...
Rendering of the text differs between selected and unselected state (when long titles using 3 or more words), when there is a picture I noticed that the text is on one sigle line when unselected (but goes outside the bounds), and is rendered on 2 lines when selected ...
Very strange !
Maybe by giving a larger width to the tabs it could be better, but I didn't find where in the code I could handle the "measurement" of the tabs ...
Using SizeMode "Fixed" isn't a solution because after that, all tabs have the same width, which is not what I want ... I just need to make more "room" inside the tabs so the text can render correctly ...
Thanks by advance for your help !
|
|
|
|
|
As a workaround, I edited the following line in the "DrawTabItem" method :
bitmapContext.DrawString(pg.Text.Trim(), this.Font, b, (RectangleF)drawRectText, textFmt);
=> pg.Text.Trim()
So I add an extra space at the end of the Text property of each Tab at design time. So the tab width is calculated using this extra space, but the printed text doesn't take care of it. Now the tabs have always enough room for rendering and the behaviour satisfies me ...
Not the cleanest solution I know, but at least for end users it will work fine !
|
|
|
|
|
You know, as far as I remember, I've used default Microsoft engine to draw unthemed and top tabs. So, what you're talking about can be MS bug . But nevertheless I'll take a look, when I have enough free time.
modified on Wednesday, July 27, 2011 5:19 PM
|
|
|
|
|
To remove it just replace two parts of code:
private unsafe int HitTest()
{
NativeMethods.TCHITTESTINFO hti = new NativeMethods.TCHITTESTINFO();
Point mousePos = this.PointToClient(TabControl.MousePosition);
hti.pt.x = mousePos.X;
hti.pt.y = mousePos.Y;
return (int)NativeMethods.SendMessage(this.Handle, NativeMethods.TCM_HITTEST, IntPtr.Zero, (IntPtr)(&hti));
} -->
private int HitTest()
{
NativeMethods.TCHITTESTINFO hti = new NativeMethods.TCHITTESTINFO();
Point mousePos = PointToClient(MousePosition);
hti.pt.x = mousePos.X;
hti.pt.y = mousePos.Y;
IntPtr htiPointer = Marshal.AllocCoTaskMem(Marshal.SizeOf(hti));
Marshal.StructureToPtr(hti, htiPointer, false);
int result = (int)NativeMethods.SendMessage(Handle, NativeMethods.TCM_HITTEST,
IntPtr.Zero, htiPointer);
Marshal.DestroyStructure(htiPointer, typeof(NativeMethods.TCHITTESTINFO));
Marshal.FreeCoTaskMem(htiPointer);
return result;
} and
unsafe
{
NativeMethods.WINDOWPOS* wp = (NativeMethods.WINDOWPOS*)m.LParam.ToPointer();
x = wp->x;
} -->
x = ((NativeMethods.WINDOWPOS)m.GetLParam(typeof(NativeMethods.WINDOWPOS))).x;
PS клевые табы, нраица ^_^
|
|
|
|
|
Maybe you're partially right and somebody, who doesn't want to use(is afraid of using; isn't permitted to use) unsafe code, should use your style. By the way, similar technique is used in VB code. But as experienced C++ Win32 programmer, why should I go around if I can go straight? Unsafe code is as cool as any other if one uses it correctly, don't you think so? To say so, it's my coding style. The possibility of unsafe coding is one of the reasons why I prefer C# to VB.
PS: Рад что понравилось
|
|
|
|
|
I think that unsafe code isn't problem just not cool.
msdn > In the common language runtime (CLR), unsafe code is referred to as unverifiable code. Unsafe code in C# is not necessarily dangerous; it is simply code whose safety cannot be verified by the CLR. The CLR will therefore only execute unsafe code if it is within a fully trusted assembly. Unsafe Code and Pointers
|
|
|
|
|
Sorry, I forgot about UAC . I always keep that bulls**t turned off.
|
|
|
|
|
I've always wondered how to solve this problem without having to go buy a 3rd party tab control.
|
|
|
|
|
Me too, and after quite long search in Web for a free control that can behave as close as possible like standard tab control I had to write it myself.
modified on Wednesday, July 27, 2011 5:22 PM
|
|
|
|
|