Lekce 9 - Upravené komponenty: TabControl, TabPage, RTB - ISIM
ChatTab.cs : TabControl
Správa tabů. Přidání a odebírání. Zjistil jsem, že GarbageCollector je flákač co nedává pozor a nevolá se při destruktoru dané komponenty aby posbáral paměť. Proto ho volám při odebírání tabu manuálně.
public void AddTab(ISIMContact contact, bool selectTab = false) { ChatTabPage ctp = new ChatTabPage(contact); if (!this.TabPages.ContainsKey(contact.id)) { ctp.convRtb.AppendText(Global.ISIMFunctions.LoadConversation(contact.id, 32)); ctp.convRtb.Scroll(); this.TabPages.Add(ctp); if (selectTab) this.SelectedTab = ctp; } } public void RemoveTab(TabPage tab) { this.TabPages.Remove(tab); GC.Collect(); }
ChatTabPage.cs : TabPage
Přidání jednotlivých komponent, nastavení velikosti a pozice. Tady co je zajmavý, je ta mezera " ". Je to nejjednodušší způsob, jak zvětšit velikost tabu, aniž bych ho musel složitě přepisovat. Chci to kvůli ikonce dostuponosti.
public ConversationRTB convRtb = new ConversationRTB(); public TextBox msgTb = new TextBox(); public Button sendBtn = new Button(); public ISIMContact contact; public ChatTabPage(ISIMContact contact) { InitializeComponent(); this.Name = contact.id; this.Text = contact.name + " ";// abych natáhnul tab a mohl si tam vykreslit ikonku dostupnosti this.contact = contact; convRtb.Size = new Size(277, 210); convRtb.Location = new Point(0, 0); convRtb.ScrollBars = RichTextBoxScrollBars.ForcedVertical; convRtb.BackColor = Color.White; msgTb.Size = new Size(277, 54); msgTb.Location = new Point(0, 212); msgTb.Multiline = true; msgTb.KeyDown += msgTb_KeyDown; msgTb.KeyPress += msgTb_KeyPress; sendBtn.Image = Image.FromFile(Global.appRunPath + "graphics" + System.IO.Path.DirectorySeparatorChar + "sendMessageIcon.png"); sendBtn.Size = new Size(50, 50); sendBtn.Location = new Point(279, 214); sendBtn.Click += sendBtn_Click; this.Controls.AddRange(new Control[] { convRtb, msgTb, sendBtn }); }
Přidání zprávy do richtextboxu. Taj používám vlastní tagy, které pak komponenta ConversationRTB odstraní a zabarví tag mezi nimi. Stejně tak pošéfí smajlíci.
public void AddChatMessage(ISIMContact contact, string text, DateTime time, string from) { // přidání tagů pro barevné nicky // uzavře neuzavřené tagy string message = TextEdit.CloseTags(text); int nickColor = 0; if (from == Global.myNick) nickColor = 1; else if (from == "ISIM") nickColor = 2; else nickColor = 3; string msgPrefix = "\n" + "[color:" + nickColor + "]" + from + " (" + time.ToString("H:mm:ss dd/MM/yyyy") + ")" + "[/color:" + nickColor + "]" + "\n"; int caretPos = 0; if (convRtb.Focused) caretPos = convRtb.SelectionStart; Global.ISIMFunctions.SaveConversation(contact.id, msgPrefix + message); convRtb.AppendText(msgPrefix + message + "\n"); convRtb.Scroll(caretPos); }
ConversationRTB.cs : RichTextBox
Zde je zajímavé například přepisování non virtual metody.
new public void AppendText(string text) { lastAppendIndex = this.TextLength; base.AppendText(text); ColorText(); EmoticonsAsImages(); }
Pak jsem si musel také upravit scrollování, protože původní komponentě to moc nejde.
[DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam); private const int WM_VSCROLL = 277; private const int SB_PAGEBOTTOM = 7; private void ScrollToBottom() { SendMessage(this.Handle, WM_VSCROLL, (IntPtr)SB_PAGEBOTTOM, IntPtr.Zero); } public void Scroll(int caretPos = 0) { if (this.Focused) { if (caretPos == 0) caretPos = this.TextLength; this.SelectionStart = caretPos; this.ScrollToCaret(); } else this.ScrollToBottom(); }