Control Panel has been part of Windows forever. In recent versions, Microsoft has been moving functionality into Settings, and some classic pages now redirect. But Control Panel is still supported, and many classic applets still exist.
That means you can still write your own Control Panel items. In this post, I’ll show one practical way to do it: a classic Control Panel applet DLL (.cpl) that exports a function called CPlApplet.
Two Ways To Add A Control Panel Item
There are two common approaches:
- Register A Normal Executable
You can write a regular EXE and register it so Control Panel can discover and launch it. This is straightforward and fully documented (search for “registering control panel items” in Microsoft documentation). - Write A CPL DLL (Classic Applet)
This is the more interesting option. You write a DLL, export a function namedCPlApplet, and Control Panel uses a defined message protocol to interact with your applet. That’s what I demonstrate here.
How Control Panel Finds Applets
There are two ways:
- Drop A
.cplInto System32
Files inSystem32with the.cplextension are picked up automatically. This is how classic Windows applets are commonly installed. The downside is obvious: writing toSystem32requires administrative privileges. - Register A CPL Located Elsewhere
You can store the CPL anywhere and register it via the registry so Control Panel can find it. Again, this is documented by Microsoft.
For a demo, placing the CPL in System32 is the simplest way to validate that everything works.
Running Applets Without Clicking The UI
Windows includes control.exe (in System32). You can use it to launch Control Panel items directly.
You can also use it to test your own CPL file by providing a path. This is useful while you’re developing because you don’t have to rely on Control Panel UI refresh behavior just to run the applet.
Project Setup In Visual Studio
Create a new project using the Visual Studio Desktop wizard and select DLL.
The wizard gives you a standard DLL skeleton (DllMain, headers, and example exports). You don’t need the example exports. What you do need is a correctly named exported function.
The Function You Must Export: CPlApplet
The easiest way to discover the exact signature and required behavior is to look at the header:
cpl.h
It contains the function prototype and the message values you need to handle.
The function must be named exactly:
CPlApplet
If the name is wrong, Control Panel won’t find it. The function uses WINAPI calling convention (stdcall).
CPlApplet receives:
- a parent window handle (useful if you show UI)
- a message indicating what Control Panel wants
- message-specific parameters
A key point: you’re not “just running a DLL.” Control Panel and your applet follow a small protocol.
$1,478
$1182 or $120 X 10 payments
Windows Master Developer
Takes you from a “generic” C programmer to a master Windows programmer in user mode and kernel mode.
The Message Protocol
A typical applet handles these messages:
CPL_INIT
Called early. This is your chance to initialize. Return TRUE to continue or FALSE to indicate failure.
CPL_GETCOUNT
Control Panel asks how many applets you provide. A single DLL can host multiple applets. For this demo, return 1.
CPL_INQUIRE
Control Panel asks for metadata about an applet: name, description, and icon. You return this data through a CPLINFO structure.
The values you provide are typically resource identifiers, not literal strings. That means you need resources in your project.
CPL_DBLCLK
Triggered when the user activates the applet. This is where you do the actual work. For a simple demo, a message box is enough.
There are other messages you can handle, but these are the minimum set to get a working item that appears in Control Panel and reacts when clicked.
Adding Resources (Strings And Icon)
For CPL_INQUIRE, create resources:
- A String Table with:
- applet name string
- applet description string
- An Icon resource
Then, in CPLINFO, reference these resources by ID.
This is how your applet appears with a proper name, description, and icon in Control Panel.
Building As A .CPL
A CPL file is a DLL with a different extension. You can make your project produce a .cpl directly by changing the output extension in project settings.
That’s convenient because you build and you immediately get something you can copy into place.
$1300
$1040 or $104 X 10 payments
Windows Internals Master
Broadens and deepens your understanding of the inner workings of Windows.
Installing And Verifying
For the simplest test:
- Build the project to produce
MyApplet.cpl(or any name). - Copy it to
C:\Windows\System32(administrator required). - Open Control Panel and refresh the view.
- Your new applet should appear.
- Double-click it and verify your
CPL_DBLCLKbehavior (e.g., a message box).
What Actually Launches A CPL
If you inspect the running processes, you’ll see your CPL is typically launched via rundll32.exe. The infrastructure loads the applet and calls into it through a Control Panel entry point.
This is useful to know for debugging, because you can run the same host process yourself.
Debugging The Applet Properly
Since this is a DLL, you can’t “run it” like a normal EXE.
Two practical options:
- Use
control.exeto launch your CPL for quick testing. - For real debugging in Visual Studio, configure the project to start rundll32.exe with the right arguments, so you can hit breakpoints reliably.
A common form looks like:
rundll32.exe shell32.dll,Control_RunDLL C:\Windows\System32\MyApplet.cpl
Once you start the host this way, you can debug the applet normally and watch the calls to CPL_INIT, CPL_INQUIRE, and CPL_DBLCLK as the Control Panel infrastructure interacts with your code.
Why This Matters For TrainSec Students
This is a straightforward example of Windows extensibility that is still present in modern Windows versions.
If you can build a Control Panel applet cleanly, you’re practicing useful fundamentals:
- building a DLL with a strict exported entry point
- working with message-driven protocols
- managing Win32 resources (strings/icons)
- understanding how Windows hosts and launches components (
control.exe,rundll32.exe) - debugging non-EXE entry points in a reliable way
Even if you never ship a CPL, the workflow and tooling patterns apply to a lot of Windows internals work. A CPL approach could be used for simple persistence.
Liked the content?
Subscribe to the free TrainSec knowledge library, and get insider access to new content, discounts and additional materials.
Keep Learning with TrainSec
This content is part of the free TrainSec Knowledge Library, where students can deepen their understanding of Windows internals, malware analysis, and reverse engineering. Subscribe for free and continue learning with us:
https://trainsec.net/library





































