• 0

ScribBox - Line Numbered RichTextBox


Question

hey, all, i remember a long time ago, i posted asking if someone knew how to apply line-numbering using pure win32 api to modify the non-client area.

i have finally done it. of course, there are some menial performance drawbacks, but if anyone is willing to help fix them, please pm or email me.

this control inherits from .net's richtextbox and is named ScribBox for the program for which it was made (Scrib).

attached is a picture, and, yes, there are 20 lines in the client area.

post-72514-1128815937.png

Edited by Ianmac45
Link to comment
https://www.neowin.net/forum/topic/382661-scribbox-line-numbered-richtextbox/
Share on other sites

6 answers to this question

Recommended Posts

  • 0

here's a quick rundown of the problems i have with it.

+ you can turn the line numbering on and off, but it doesn't clear the side bar when turning it off.

+ painting performance

here's a quick rundown of what awesome cool features this control has

+ a premade working context menu

+ extra properties such as FirstVisibleLine, LastVisibleLine, CurrentLine

+ Delete functionality (as if you pressed the Delete key)

+ Go To Line functionality

it's really awesome.

  • 0

ok, since no one has actually replied to this post. i'm simply going to post the main part of the code. the only things i know are missing are some properties/variables and all win32 objects/methods. this exact code produced the picture above.

protected override void WndProc(ref Message m)
{
	//this method mainly controls how the line numbers are painted
	//so we gotta skip it if it's not wanted or if it's designtime
	if(this.DesignMode || !showNumbers)// || !System.Diagnostics.Debugger.IsAttached)
	{
  base.WndProc(ref m);
  return;
	}


	switch(m.Msg)
	{
  case (int)Win32.WM.NCCALCSIZE:
  	if(m.WParam.ToInt32() != 0)
  	{
    Win32.NCCALCSIZE_PARAMS p = (Win32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(Win32.NCCALCSIZE_PARAMS));
    p.rgrc0.Left = sideWidth;
    Marshal.StructureToPtr(p, m.LParam, true);
  	}

  	break;

  case (int)Win32.WM.NCPAINT:
  	IntPtr hDC = Win32.GetWindowDC(m.HWnd);
  	Graphics g = Graphics.FromHdc(hDC);

  	PaintLineNumbers(g);

  	//cleanup
  	g.Dispose();
  	Win32.ReleaseDC(m.HWnd, hDC);

  	//need to redraw client area, because sometimes it simply disappears
  	base.Refresh();

  	break;
	}

	base.WndProc(ref m);
}

private void PaintLineNumbers(Graphics g)
{
	//set graphics environment
	g.Clear(this.BackColor);

	//init drawing utensils
	Color numColor = Color.FromArgb(0, 128, 128);
	Brush br = new SolidBrush(numColor);
	Pen pen = new Pen(numColor);
	int height = 3;

	//draw visible line numbers only
	for(int i = FirstVisibleLine; i <= LastVisibleLine; i++)
	{
  //gets line number as right-justified string
  string text = " " + (i + 1).ToString().PadLeft(this.Lines.Length.ToString().Length);
  g.DrawString(text, this.Font, br, 0, height);
  height += this.Font.Height;

  //if there is more than one line, this statement is necessary 
  //to prevent printing one more line number than needed
  if(i == LastVisibleLine - 1)
  	break;
	}

	//draw line seperating numbers from text
	pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
	g.DrawLine(pen, sideWidth - 1, 1, sideWidth - 1, this.Height);
}

anyway, i really need help with debugging and improving it's speed. i'd also like to implement some other features, but if anyone is willing to help, i'd really appreciate it.

  • 0

Speed improvements:

+ use the bounding box of the HRGN that you'll get thru the WM_NCPAINT to only update the necessary parts.

+ fall back to plain old GDI calls.

+ don't do an invalidate on the whole clientarea in the WM_NCPAINT, but figure out what's going wrong (might need to not pass the WM_NCPAINT to the old WNDPROC).

+ check if caching makes things faster (could also raise a costly active pagefault).

  • 0

i still have to look at the first two, but i think the first item kinda ties in with the third item

excluding the call to the old wndproc for ncpaint did speed it up a bit, but then the scrollbars weren't painted properly. also, just like the code says, i need the base.Refresh() call so it works with the rest of my app.

  • 0

WM_NCPAINT:

a) clip your update rectangle with the HRGN being passed, creating a new HRGN.

b) pass that new to base.wndProc(WM_NCPAINT, reinterpret_cast<WPARAM>(yourNewHrgn), 0L);

c) do your painting.

GDI calls:

GDI calls are much faster than GDI+ calls in current implementations. Since GDI is used to draw the richeditbox in the first place, the looks will also be more consistent.

HRGN that you get:

see WM_NCPAINT.

base.Refresh() call:

seems like a fundamental flaw in your application then. There is no reason that you should invalidate the client-area in the non-client area painting proc.

  • 0

ok, i updated the ncpaint case to this (not much change, just a little here and there from msdn and what andreas told me)

case (int)Win32.WM.NCPAINT:
	if((int)m.WParam != 1)
  break;

	//painting
	IntPtr hDC = Win32.GetWindowDC(m.HWnd);
	Graphics g = Graphics.FromHdc(hDC);
	PaintLineNumbers(g);

	//cleanup
	g.Dispose();
	Win32.ReleaseDC(m.HWnd, hDC);
	base.DefWndProc(ref m);

	return;

but, for the plain old GDI calls, is there some sort of reference that i can use to figure out what each function does and how to use it?

i sorta tried the caching of the side bar, but it stole system resources like crazy. maybe i'll try it again later, but definitely not now

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • FocusOn Image Viewer 1.32 by Razvan Serea FocusOn Image Viewer is a fast, lightweight, and user-friendly photo viewer for Windows. It supports various image formats, offers basic editing tools, EXIF data display, and batch renaming. With a clean interface, slideshow mode, and easy navigation, it’s ideal for quickly viewing and organizing photos without unnecessary complexity or system resource usage. FocusOn Image Viewer key features: Auto Organize: Automatically sorts photos by date using your chosen template. Explorer View: Browse and manage images with thumbnails; includes basic edits like resize and rotate. Photo Editing: Crop, apply filters, correct colors, add borders or text. Non-Destructive Edits: Original images remain untouched. Photo Sharing: Post directly to blogs, Twitter, and Facebook. Email Support: Send selected images via email. Print Options: Print to fit paper size, preserve aspect ratio, or fit multiple images per page. Slideshow: View selected photos in a slideshow. EXIF Tools: View or remove EXIF data. Scanning: Import from TWAIN or WIA-compatible scanners. Set as Background: Quickly set any image as desktop wallpaper. Batch Rename: Rename images in bulk using templates. Resize Images: Resize with optimized or custom resampling methods, including multi-step resizing. Thumbnail Sizes: Choose from thumbnail sizes between 32–256 pixels. Format Support: Compatible with over 100 image formats. FocusOn Image Viewer 1.32 changelog: Added Ghostscript(AI, PDF) DPI option Fixed transparency issue when saving PDF document as image Other improvements and bug fixes Download: FocusOn Image Viewer 64-bit | Portable 64-bit | ~7.0 MB (Freeware) Download: FocusOn Image Viewer 32-bit | Portable 32-bit View: FocusOn Image Viewer Website | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
    • Wall cabinet: Fiber connection (1Gbps) Patch panel 2.5Gbps Router A mini PC with Ryzen 5800H CPU and 32GB DDR4 RAM, for network related tools (Portainer, Pi-Hole, Cloudflared, Tailscale, Uptime Kuma, Wetty) A headless server running Proxmox: AMD Ryzen 9 9950X CPU, 96GB DDR5, RTX 3090 24GB GPU, 10Gbps NIC, and a bunch of NVMs, SATA SSDs, HDDs A VM with TrueNAS for backups and media server via Jellyfin, passing through the SATA storage controller A VM with an Ubuntu server acting as a web and a GPU server for AI workloads, and a TeamCity build/deploy agent for my personal projects This setup has evolved many times for the last 2 years, I have not gone completely crazy, yet (I think), but still experimenting, still learning, it is a fun and rewarding experience having a home lab!
    • Microsoft PC Manager 3.17.4.0 (Offline Installer) by Razvan Serea With Microsoft PC Manager, users can easily perform basic computer maintenance and enhance the speed of their devices with just one click. This app offers a range of features, including disk cleanup, startup app management, virus scanning, Windows Update checks, process monitoring, and storage management. Microsoft PC Manager key features: Storage Manager- easily uninstall infrequently used apps, manage large files, perform a cleanup, and set up Storage Sense to automatically clear temporary files. Health Checkup feature -scans for potential problems, viruses, and startup programs to turn off. It helps you identify unnecessary items to remove, optimizing your system's performance. Pop-up Management - block pop-up windows from appearing in apps. Windows Update - scans your system for any pending updates. Startup Apps - enable or disable startup apps on your PC, allowing you to optimize your system's startup performance. Browser Protection - rest assured that harmful programs cannot alter your default browser. Also enables you to change your default browser. Process Management - allows you to conveniently terminate any active process, ensuring optimal system performance and resource utilization. Anti-virus protection - Fully integrated with Windows Security. Safeguard your PC anytime. Quick Steps: Download Microsoft PC Manager Offline Installer (APPX/MSIX) with Adguard Adguard serves as a third-party online service, offering a user-friendly method for directly downloading appx, appxbundle, and msixbundle files from the Microsoft Store. Official download links will be generated for both the app's various versions and its dependency packages. How to download Microsoft PC Manager Offline Installer (APPX/MSIX) 1. Initially, you must find the app URL within the Microsoft Store. Access the Microsoft Store via your browser and search for "Microsoft PC Manager". Once located, copy the app URL, which includes the product ID, either from the address bar or from the provided link below. https://apps.microsoft.com/detail/9PM860492SZD 2. Now paste the app URL into the designated area, then click the check mark button to produce a direct download link. 3. To download, right-click the relevant link and select “Save link as…” from your browser's menu. Occasionally, Microsoft Edge may flag the download as insecure. In such cases, consider utilizing alternative browsers such as Google Chrome or Firefox to successfully complete the download. Microsoft PC Manager is a completely free tool optimized exclusively for use on Windows 10 (version 1809 or newer) and Windows 11. Download: Microsoft PC Manager 3.17.4.0 | from Microsoft Store View: Microsoft PC Manager Home Page Get alerted to all of our Software updates on Twitter at @NeowinSoftware
    • You might want to update to 1TB drive.  They are not very expensive these days, there are plenty of options - simple look I would think you could find a 1TB ssd or even nvme somewhere between 50 and 100 bucks. when I have moved to larger ssds in laptop in the past, you can just connect the drive via usb - image.  Then take the old drive out, put in the new drive and there you go..  If your concerned about how much space you have left this prob your best bet..   
    • I see! Wasn’t aware of that. Even though they started off with desktop app for Mac before Windows. Should be on it’s way soon! 🤞
  • Recent Achievements

    • First Post
      Johnny Mrkvička earned a badge
      First Post
    • Week One Done
      viraltui earned a badge
      Week One Done
    • One Month Later
      serfegyed earned a badge
      One Month Later
    • Dedicated
      firey earned a badge
      Dedicated
    • Dedicated
      fettermanj earned a badge
      Dedicated
  • Popular Contributors

    1. 1
      +primortal
      644
    2. 2
      ATLien_0
      226
    3. 3
      Michael Scrip
      223
    4. 4
      Xenon
      153
    5. 5
      +FloatingFatMan
      144
  • Tell a friend

    Love Neowin? Tell a friend!