Pharo-OS-Windows

Description

Support for Windows operating system for Pharo

Details

Source
GitHub
Dialect
pharo (65% confidence)
License
NOASSERTION
Stars
14
Forks
7
Created
July 3, 2018
Updated
Oct. 6, 2025
Topics
pharo

Categories

System / OS

README excerpt

# Pharo-OS-Windows
Support for Windows operating system for [Pharo](https://www.pharo.org)

# The OS PROJECT FOR PHARO

# Introduction

[Pharo][1] with an integrated external interface offers new ways to interact with the ouside world from within your Smalltalk image. Beside interacting with external libraries from other OpenSource projects or commercial libraries it is also very useful to call and use the underlying operating system platform.

The **[OS project][6]** on SmalltalkHub is intended to provide such a layer on top of UFFI. Starting with the Windows operating system our hope is that other will jump onto the bandwagon and help to extend it to support other platforms (Mac, Linux, ...) as well. 

It is possible to generate Pharo code for native interfaces - but we prefer handcrafted code to wrap the native platform since often the underlying API's and names are not very well designed. This way we can make sure to provide a more object-oriented abstraction and more alignment with the Pharo philosophy to provide a clean and innovative environment.  

### Requirements

The **[OS project][6]** requires at least Pharo 3.0. You can grab a copy of Pharo for your platform from the [Pharo file server][3].

### Packages and Naming

The project **[OS project][6]** defines a standard for package names - if you want to support the project it would be necessary to follow it. 
The first part of a package name has to begin with **"OS-"** followed by the name of the platform (for instance *"OS-Windows"* or "OS-Mac"). 

Any following package name is up to the packages that will be provided. It is a good style to provide some kind of ***Core*** package, like *"OS-Windows-Core"* defining functionality common to other dependent packages. 
It is also a good practice to separate the tests in an own packages so they can be loaded only if required.   

----------------------------------------------------------------------
# Windows Support 
## OS-Windows project

Windows support is defined in the project The **[OS-Windows][2]** - a subproject of **[OS project][6]** 
 
### Installation 

You can install the packages either directly from the Pharo configuration browser or with the following script: 

```Smalltalk
Metacello new 
	repository: 'github://astares/Pharo-OS-Windows/src';
	baseline: 'OSWindows' ;
	load
```

By default all packages are loaded as well as the tests. Open the test runner and run all tests from the "OS" category to see if its fully working and report any issue you may find.

----------------------------------------------------------------------
### Debugging
#### Pharo debugging vs. native debugging
There is nothing more helpful for development than a debugger that shows you your code and lets you walk through it. Pharo has a very powerful interactive debugger. Did you know that (compared to traditional development environments in other languages) you can save your Pharo image while debugging and open it the next day to continue to step through your program? Just try it! 
 
If you work with native environments like Windows it may (in very rare cases) be very helpful to additionally use external debug possibilities. This is useful for VM developers or people who dive deep down into the low level world of assembler (which is also possible from within Pharo with NativeBoost and ASMJit, less with new UFFI). Additional external debug support can also be helpful if you run the Pharo image headless without  any user interface.

In these rare cases you can use:

```Smalltalk
WinDebugger outputDebugString: 'Some debug info from my program'
```

to write to the windows debug stream. While running can catch and display such messages with various tools like "DebugView" or dbmon.exe. You can get these tools for free on the internet.

It can also be possible that you want to know if Pharo (the virtual machine of Pharo to be precise) is running under the control of a debugger. The following expression can help you here:

```Smalltalk
WinDebugger isDebuggerPresent
```

----------------------------------------------------------------------
### Processes and Threads
#### Process creation - nonblocking

The class ***WinProcess*** provides access to native OS processes of Windows - so you can use it to start other native processes: 

```Smalltalk
WinProcess createProcess: 'explorer.exe'
```

It returns also an instance of ***WinProcessInformation*** which you can use to query for the PID of the new process:

```Smalltalk
(WinProcess createProcess: 'explorer.exe') processId
```

or the new process itself:

```Smalltalk
(WinProcess createProcess: 'explorer.exe') process
```

When you start a new operating system process this way you will notice that Pharo continues independently. So it is not blocked and both processes run in parallel. 

#### Process creation - blocking

You may have the requirement that you start an external operating system process and wait until its processing is finished before you continue within your Pharo program. Here is an example:

```Smalltalk
WinProcess createAndWaitForProcess: 'cmd.exe'.
Transcript show: 'The external process just finished'.
```

This opens a new command line window and the Pharo process (virtual machine process) is blocked until you either enter "EXIT" or close the console window. 
After that Pharo continues its work and writes to the Transcript.

#### The VM Process

When you start Pharo you start the virtual machine which is a normal platform dependent executable file that runs as a native operating system process. You can access this process of the Pharo virtual machine using the following expression:

```Smalltalk
WinProcess currentProcess
```

By default the VM runs with normal priority which you can check with:

```Smalltalk
WinProcess currentProcess isNormalPriorityClass
```

which should return true.

Any process running on the operating system is associated with a PID (Process Identifier). If you start a second VM you will start a new native OS Process with a different process ID.
Use this expression to get the PID:

```Smalltalk
WinProcess currentProcessId
```

Compare that with the PID that is displayed in the Windows TaskManager.

You can also query for some startup informations:

```Smalltalk
WinProcess startupInfo wasStartedFromAShortcut
```

or

```Smalltalk
WinProcess startupInfo title
```

to find out how and where the virtual machine was started.

#### Threads

The Pharo VM provides its own internal managed process handling to stay portable. Also the number of the underlying operating system processes may be limited - which is no problem for you if you use Pharo.  

So in a simple VM Pharo runs within a single thread within a single OS process. You can access this thread using:

```Smalltalk
WinThread currentThread
```

and 

```Smalltalk
WinThread currentThreadId
```

Note that there are implementation (like Cog-VM) that provide a multithreaded variant of the VM.

----------------------------------------------------------------------
### The Windows User Interface

#### Windows

In a graphical environment like Windows, a window is a rectangular area of the screen where the application displays output and receives input from the user. 

So "Windows" are from the API point of view not only the framed windows that your move around. Also an edit widget or a list view in windows is represented as an own window, usually these are referred as child windows. Even the desktop background itself is an own Window.

You can get the active window using:

```Smalltalk
WinWindow activeWindow
```

and query or manipulate it:

```Smalltalk
WinWindow activeWindow title inspect.
WinWindow activeWindow title: 'Pharo main window title'	
```

If you have a window instance you can easily find out about the area 
it fills on the screen:

```Smalltalk
WinWindow desktopWindow windowRectangle
```

or set its position

```Smalltalk
WinWindow activeWindow moveTo: 20@10
```

You can also show and hide a window as this example proves:

```Smalltalk
|win|
win := WinWindow activeWindow.
win hide.
(Delay forSeconds: 2) wait.
win show
```

...

----------------------------------------------------------------------
### Graphics

#### Basic drawing

Any native window in the Windows operating system provides a device context (DC). You can easily access it if you have a window object. Since Pharo runs in a single native window we can access its windows device context easily:

```Smalltalk
WinWindow pharoWindow deviceContext 
```

The device context (represented by instances of class ***WinDeviceContext***) can be used to draw:

```Smalltalk
WinWindow pharoWindow deviceContext 
     drawRectangle: (10@10 extent: 100@100)
```

You can also access the device context of the whole Window desktop allowing to draw outside of the Pharo window

```Smalltalk
WinDeviceContext desktopDeviceContext  
    drawEllipse: (0@0 extent: 100@100)
```

#### Why draw using native Windows-API
Pharo has several possibilities to draw - by default there is Morphic that draws
inside the Pharo window. There is also Athens (which is also based on NativeBoost) allowing you to work with vector graphics and that is portable across several platforms.

But as you have seen from the desktop example with native access to the windows graphic system (GDI and GDI+) in this project it is also possible to draw outside the Pharo window. So by default one should go the usual Pharo route (Morphi, Athens) for drawing and use the mentioned way only if required.

----------------------------------------------------------------------
### Dialogs
#### MessageBox

Windows provides by default a message box that can be used to inform the user. Have a look at class ***WinMessageBox***. It is still unfinished but you can test:

```Smalltalk
WinMessageBox test
```

----------------------------------------------------------------------
### Shell support

#### Open a URL
You can easily use the class WinShell to open a web browser on a given URL.

```Smalltalk
← Back to results