> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/uwp/ui-customization/custom-tool.md).

# Create a custom tool for your UWP viewer

Learn how to create custom tools for PDFViewCtrl with ease. Explore tools in the PDFViewCtrlTools project, handle events efficiently, prevent input handling, and lock documents effectively. The Apryse

Creating a custom tool to use with the `PDFViewCtrl` is fairly straight forward. There are several tools implemented in the `PDFViewCtrlTools` project already. These tools can be used as a base for many other tools or as a reference for a new tool. In order to create your own tool, we suggest looking at the `PDFViewCtrlTools` project.

When creating a new tool, there are a few important elements that needs to be handled.

## Events raised on the PDFViewCtrl

First, we need to handle the events of the `PDFViewCtrl`. This is easily done by subscribing to the events using standard syntax. The standard events to subscribe to are `PointerPressed`, `PointerMoved`, and `PointerReleased`. However, additional events, such as `PointerCancelled` and `PointerCaptureLost` are also important.

## Preventing the PDFViewCtrl from handling the input

Preventing the `PDFViewCtrl` from handling the input is best done when the pointer is pressed. You will receive the `PointerPressed` event, at which point you can call `PDFViewCtrl.SetZoomEnabled(false)` and `PDFViewCtrl.SetScrollEnabled(false)`. Remember to call the same two functions but with True on the `PointerReleased` event.

Once the user starts to manipulate the `PDFViewCtrl`, especially with touch, such as a scrolling or pinching, the event chain will be taken away from the UI thread to be handled internally by the Control itself. This is standard procedure for controls like the `ScrollViewer` or `FlipView` in Windows Store Apps. This allows the events to be processed in a background thread, and it keeps the UI thread responsive. Once the `PDFViewCtrl` starts to scroll, you will not be able to get any pointer or Manipulation events until it has come to a rest.

## Knowing when to lock the document

It is important to lock the document whenever you read any information from it. PDFNet provides two types of locks. A read lock which allows for concurrent reading, as well as a write lock which grants the process exclusive access to the PDFDoc. The write lock is only necessary when modifying information in the document, such as when pushing back annotations or changing their appearance. Please see the `PDFViewCtrlTools` project to learn how and when to use these locks.

## Converting between different coordinate spaces

When working with the `PDFViewCtrl`, there are three spaces to be aware of. There is a Screen space, which is a coordinate system relative to the PDFViewCtrl itself. The point 0, 0 is in the PDFViewCtrl's top left corner. There is a page space, which is the coordinate system relative to a particular page. PDF page coordinates start with 0, 0 in the bottom left corner, unless rotated. Note that the page's CropBox, which is the region visible in the PDFViewCtrl, doesn't always start at 0, 0 though. And finally there is the space of the Canvas that you can get from calling PDFViewCtrl.GetAnnotationCanvas(). This canvas is the minimum bounding rectangle (starting with 0, 0 in the top left) around all the pages in the current scrollable region (for example, at very low zoom levels, the x-coordinate 0 might be close to the center of the `PDFViewCtrl`). You can use `PDFViewCtrl.ConvAnnotationCanvasPtToScreenPt` and `PDFViewCtrl.ConvScreenPtToAnnotationCanvasPt` to convert between `PDFViewCtrl` and AnnotationCanvas coordinates. Note that the `PDFViewCtrl` has an internal concept of a canvas which is different from this canvas. Therefore, `PDFViewCtrl.ConvPagePtToCanvasPt` will not actually work on the Canvas from GetAnnotationCanvas.

When capturing input, you usually deal with Canvas or Screen coordinates. For example, inside the `PointerPressed` handler, `Windows.Foundation.Point downPoint = e.GetCurrentPoint(mPDFView).Position` will give you a point in Screen space. When pushing back an annotation, this has to be converted to Page space of the page you want to add the annotation to. You can convert between these spaces with the help of the PDFViewCtrl. For example, `int pgNumber = PDFViewCtrl.GetPageNumberFromScreenPoint(double x, double y)` will give you the page that you would be touching if x, y was the point of your finger in screen space. Then, calling `PDFViewCtrl.ConvScreenPtToPagePt(DoubleRef px, DoubleRef py, int pgNumber)` will give you what point this is in page space. These conversions are used throughout the tools library. Also, the base Tool class contains some convenience functions to perform these conversions on full rectangles (`pdftron.PDF.Rect`).

## We will also take a quick look at the tool loop in the ToolManager class, to better understand how that is used

In the PDFViewCtrlTools project, the `ToolManager` is the only class that directly subscribes to the PDFViewCtrl's events. This provides a centralized location to managed the different tools. The `ToolManager` forwards the event to various tools, inside a loop. The reason for this loop is that it allows a tool to process an event, decide if another tool should be handling it, and then let the `ToolManager` know that another type of tool should be getting the event. This is done by changing the next tool mode to that of the tool that should be processing the event.

For example, the Pan tool will, when a Tapped event occurs, examine the contents of the point where the tap occurred. If the tap happened on a link, it will set the mNextToolMode to `ToolType.e_link_action`. Once the pan tool returns, the `ToolManager` will notice that the NextToolMode is different from the current `ToolMode`, it will create a `LinkAction` tool, and then call the Tapped handler on that tool. The link tool will then read the link and execute the associated action.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/uwp/ui-customization/custom-tool.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
