LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Text Rendering in LabVIEW

More on interfaces (related to my previous post on buttons). On the left in each picture is a button from a Python-based application in what I am pretty sure is Calibri. On the right is LabVIEW's version of Calibri and Calibri light in a Fuse button. Top is actual size more or less. Bottom is magnified. Is there a way to get crispier text in LabVIEW? What makes the difference? These a screen shots from side-by-side windows?  Interestingly, the Mac version of LabVIEW has the more Python-like text. -- David

 

FlatCat_0-1791561116130.png

FlatCat_2-1791561431589.png

 

 

 

 

0 Kudos
Message 1 of 10
(349 Views)

Hi David,

 


@FlatCat wrote:

What makes the difference?


What is your screen scaling set to?

How do those buttons look like when you set a scaling of 100%?

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 2 of 10
(314 Views)

Hi Gerd, 

 

I think you're right that it's a screen scaling issue. I am on the "Recommended" setting of 125%. On 100%, the difference between the apps goes away. NI Support suggested the procedure below, which helps a lot (although not 100%). 

 

David

 

  • Close LabVIEW
  • Right-click LabVIEW.exe
  • Select Properties
  • Open the Compatibility tab
  • Click Change high DPI settings
  • Enable Override high DPI scaling behavior
  • Set Scaling performed by to System (Enhanced)
  • Reopen LabVIEW and compare the same button again
0 Kudos
Message 3 of 10
(300 Views)

@FlatCat wrote:

Hi Gerd, 

 

I think you're right that it's a screen scaling issue. I am on the "Recommended" setting of 125%. On 100%, the difference between the apps goes away. NI Support suggested the procedure below, which helps a lot (although not 100%). 

 

David

 

  • Close LabVIEW
  • Right-click LabVIEW.exe
  • Select Properties
  • Open the Compatibility tab
  • Click Change high DPI settings
  • Enable Override high DPI scaling behavior
  • Set Scaling performed by to System (Enhanced)
  • Reopen LabVIEW and compare the same button again

Would you have to do the same for an exe that is created? Could that be automated for an exe? Hate to ask a customer to do that.

0 Kudos
Message 4 of 10
(270 Views)

@mcduff wrote:
...
  • Enable Override high DPI scaling behavior
  • Set Scaling performed by to System (Enhanced)
  • Reopen LabVIEW and compare the same button again

Would you have to do the same for an exe that is created? Could that be automated for an exe? Hate to ask a customer to do that.


Yes, of course. Just create a manifest with PerMonitor DPI awareness:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
  <windowsSettings>
    <!-- Overrides legacy false/true setting on Windows 10/11 -->
    <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
    <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
  </windowsSettings>
  </application>
</assembly>

Then simply embed it into the LabVIEW-built application:

mt.exe -manifest ApplicationHiDPI.exe.manifest -outputresource:ApplicationHiDPI.exe;#1

After that, the application will no longer be scaled. So easy. If you signing application with code signing certificate, then do it after manifest embedding, otherwise this will break digital signature.

Message 5 of 10
(239 Views)

I am to new manifests, and I notice that mt.exe is not even on my computer and needs to be installed (apparently as part of Windows SDK). In which case, doesn't it also need to be installed on the user's computer so it can be executed there by the built app? Does mt.exe then need to be part of the Installer (as an additional installer, perhaps)?

On an even simpler level, where does mt.exe get executed? Within the application via system exec.vi? 

0 Kudos
Message 6 of 10
(204 Views)

@FlatCat wrote:

I am to new manifests, and I notice that mt.exe is not even on my computer and needs to be installed (apparently as part of Windows SDK). In which case, doesn't it also need to be installed on the user's computer so it can be executed there by the built app? Does mt.exe then need to be part of the Installer (as an additional installer, perhaps)?

On an even simpler level, where does mt.exe get executed? Within the application via system exec.vi? 


Basically it is part of your application build process.

 

1) Built your LabVIEW application

2) Run mt.exe to add this (and other manifest settings) into the created exe file.

3) If you have a signing certificate and need to sign your executable so users in high security restricted IT environments won't be prompted with ugly warning dialogs about untrusted software, sign your executable now.

4) Optionally create a LabVIEW installer

5) Distribute exe or installer to your users

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 7 of 10
(161 Views)

@FlatCat wrote:

I am to new manifests, and I notice that mt.exe is not even on my computer and needs to be installed (apparently as part of Windows SDK). In which case, doesn't it also need to be installed on the user's computer so it can be executed there by the built app? Does mt.exe then need to be part of the Installer (as an additional installer, perhaps)?

On an even simpler level, where does mt.exe get executed? Within the application via system exec.vi? 



As Rolf already explained, this only needs to be executed once as one of the final steps in the build process. The manifest is embedded into the executable’s Resources section (the same section that stores the application icon, for example), just open LabVIEW-built Application in any text editor, search for dpiAware string an you will see.

 

And yes, "mt.exe" is part of the Windows SDK, sorry, I didn't mentioned it before. It is also installed with NI CVI (as part of SDK) or with the latest SDK under "C:\Program Files (x86)\Windows Kits\..."

 

However, the good news is that you don’t actually need to install the SDK to obtain just mt.exe. Don’t underestimate modern LLMs — you can ask almost any Copilot to generate a small script that modifies a manifest, and it will do so easily. Here is a simple Python example, just a few lines:

 

from pathlib import Path
import lief # python -m pip install --upgrade lief

exe_path = Path("Application.exe")
manifest_path = Path("manifest.xml")
output_path = Path("App_with_manifest.exe")

if not exe_path.is_file(): # Check that the input files exist.
    raise FileNotFoundError(f"Executable not found: {exe_path}")
if not manifest_path.is_file():
    raise FileNotFoundError(f"Manifest not found: {manifest_path}")

manifest = manifest_path.read_text(encoding="utf-8") # Read the manifest
image = lief.PE.parse(str(exe_path)) # Parse the existing executable.
if image is None:
    raise ValueError(f"Could not parse PE executable: {exe_path}")
image.resources_manager.manifest = manifest # replace the manifest.
image.write(str(output_path)) # Write the modified executable
print(f"Manifest embedded successfully: {output_path}")

A prefer Rust personally, works as well

Spoiler
use editpe::Image;
use std::fs;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let exe_path = "Application.exe";
    let manifest_path = "manifest.xml";
    let output_path = "App_with_manifest.exe";

    // Read the manifest as UTF-8 text.
    let manifest = fs::read_to_string(manifest_path)?;

    // Parse the existing executable.
    let mut image = Image::parse_file(exe_path)?;

    // Keep existing resources and create a resource directory if absent.
    let mut resources = image.resource_directory().cloned().unwrap_or_default();

    // Add or replace the application manifest.
    resources.set_manifest(&manifest)?;

    // Update the executable's resource directory.
    image.set_resource_directory(resources)?;

    // Write the modified executable to a separate file.
    image.write_file(output_path)?;

    println!("Manifest embedded successfully: {output_path}");

    Ok(())
}

By the way, you can explore your executable using tools such as TotalPE2 by Pavel Yosifovich (author of several Windows Internals books): https://github.com/zodiacon/TotalPE2/releases

 

And, as mentioned above, if you inspect the original LabVIEW application, you’ll see that it already contains a manifest:

2026-10-11 02.48.11 - Application.exe - Total PE.png

A more elegant solution is therefore to modify the existing manifest instead of replacing it completely. You can still use the script above (or mt.exe) — simply extract the manifest from the LabVIEW EXE, update the DPI settings manually, and embed it again. Or you can ask "AI" to extend the script above with a bit of “intelligence” to patch the manifest automatically.

 

Message 8 of 10
(116 Views)

Thanks both to you and to Rolf for your extensive explanations. I will explore. How did I not know of this setting for the 3 decades I've been using LV? The difference with the DPI setting on is clear. 

 

I don't underestimate LLMs, but I have resisted them so far. That's clearly getting harder to do. 

 

David

 

0 Kudos
Message 9 of 10
(107 Views)

@FlatCat wrote:

Thanks both to you and to Rolf for your extensive explanations. I will explore. How did I not know of this setting for the 3 decades I've been using LV? The difference with the DPI setting on is clear. 

 

 


You're welcome!

 

Well, for probably three decades you worked with 100% scaling, and it was never actually necessary.


The first time I ran into this problem was on a laptop with a 15-inch 4K UHD display (3840×2160), around 7–8 years ago. The screen was fantastic — vibrant, brilliant, crisp, and clear (and with touch!). At roughly 300 DPI it looked amazing; I couldn’t see a single pixel. But the LabVIEW UI was a complete nightmare as hell. A comfortable scaling level was around 175%, and LabVIEW became very blurry when scaled. At 100% (1:1) it was sharp, but extremely *ing small. I could fit a huge amount of code on one screen block diagram at such a high resolution,but you needed to have eagle eyes to work like that at 1:1 scale. Finally, I gave the laptop to my daughter as a gift, because such an remarkable screen was absolutely useless for me, thanks NI.

 

Technically, NI should support HiDPI, and they actually attempted this with LabVIEW NXG — a project that obviously failed and was discontinued, unfortunately. But its GUI was based on WPF/C#, everything was vector-based, and scaling was handled properly, staying sharp at any DPI scale.

 

With “classic” LabVIEW it’s not so simple by design because GDI rendered, and the same applies to applications built with LabVIEW. Controls and indicators are not scalable in that sense. For example, I’m writing this comment on a 15.5‑inch screen with a native resolution of 1920×1080. Windows recommends 125% scaling. This scaling does not mean the panel resolution becomes 1536×864. The physical resolution stays the same — it simply means your application should render all controls and indicators at scale 1.25 so they are not too small. So, to get full screen app we should still have FP at 1920x1080, but put "1,25 times" less UI on it. If the application doesn’t do that, it tells Windows “I’m not dpiAware, please scale me,” and Windows stretches everything as a bitmap at 1.25× as best as it can, without any awareness of the content. And in this case we must not exceed 1536×864 size of our FP, otherwise will be off screen on 1920×1080 monitor). The result is an unsharp UI.

With the manifest, we lie to Windows and say “don’t scale me, I’m DPI-aware.”
But to actually be DPI-aware in LabVIEW, we would need multiple front panels with different layouts for commonly used scaling factors, detect the current scaling programmatically (possible via WinAPI), and show the user the front panel that matches the current DPI.

 

Screenshot 2026-10-11 10.55.52.png

 

Alternatively, we could dynamically rescale and reposition everything — not only sizes, but also fonts, caption text, graph line thicknesses, icons, etc. — using property nodes. But that would be a development nightmare as well. The same applies to NI CVI, although at least there the UI is separated into a *.uir file and the code.

0 Kudos
Message 10 of 10
(63 Views)