by Wojciech Sura

How to create a pure WinAPI window?

Have you ever wondered, how does the mostly low-level Windows application look? I mean, one, which has at least one window. Well, here you go:

[cpp]#include <Windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
{
PostQuitMessage(0);

return 0;
break;
}
default:
{
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
}

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// Registering window class
WNDCLASSEX winClass;
winClass.cbClsExtra = 0;
winClass.cbSize = sizeof(WNDCLASSEX);
winClass.cbWndExtra = 0;
winClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
winClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
winClass.hInstance = hInstance;
winClass.lpfnWndProc = WindowProc;
winClass.lpszClassName = L"MainWindowClass";
winClass.lpszMenuName = NULL;
winClass.style = CS_HREDRAW | CS_VREDRAW;

if (!RegisterClassEx(&winClass))
return -1;

// Creating a window
HWND mainWinHWND = CreateWindowEx(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
L"MainWindowClass",
L"WinAPI window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
640,
480,
NULL,
NULL,
hInstance,
NULL);

if (!mainWinHWND)
return -1;

ShowWindow(mainWinHWND, SW_SHOW);

// Processing messages
MSG message;
BOOL getMsgResult;

while ((getMsgResult = GetMessage(&message, NULL, 0, 0)) != 0 && getMsgResult != -1)
{
TranslateMessage(&message);
DispatchMessage(&message);
}

return message.lParam;
}[/cpp]

Now a few words of comments:

  1. Windows applications are driven by so-called messages: most of events are reported to an application in the form of a message. System maintains a message queue for each process and allows application to query for incoming messages. Message processing, however, has to be implemented by the programmer manually (the last while loop is usually called “main message loop”).
  2. A message is a simple structure consisting of the following fields:
    • A message code (int), for example mouse left button down is 0x201 = 513 (dec)
    • Two parameters: WParam and LParam (ints). If there’s a need to pass more data, LParam usually represents a pointer to bigger structure.
    • Target window handle (HWND, pointer)
  3. Applications receive a lot of messages, but fortunately Windows API provides a function, which processes them in a default way, if programmer didn’t planned anything special for them.
  4. Before window may be created, programmer has to define special window class, which describes window’s properties.
  5. Now an interesting fact. A “window” in terms of Windows API is not only awindow. Actually, every single UI object: button, checkbox, listbox etc., is a window and has its own window class. Windows API provides a set of default classes for most common controls you might want to use. I guess, that this is the real reason for the operating system to be named “Windows”

Before you urge to write a new application in pure WinAPI, here’s the equivalent of mentioned source code in C#/Windows Forms:

[csharp]Form form = new Form();
form.Show();[/csharp]

by Njål

Install4j: Installing to the home directory of user

 

Install4j is a great installer that wraps Java application into a native installer package & launcher (executable). It can embed JRE, so you won’t have to worry about user that don’t have Java installed.

When releasing our application I wanted to offer our customers two installers:

  1. One standard installer which installs the application to the home directory of the user. This application auto updates itself. No admin privileges required.

  2. One Terminal Server version which installs the program for all users. Admin privileges are needed to install, and auto updates are disabled since normal users can’t update the application anyways.

(This is the way Chrome and a lot of other great apps do it)

Making a Terminal Server installer was very easy. Just enable “For All Users” and set “Elevation”.

Here’s how you make the installer install into a users home directory by default:

context.setInstallationDirectory(new File(System.getProperty("user.home") + "/ArgusClient"));

 

image

 

 

The installer now suggests your home folder:image

by Njål

Downloading blobs from Windows Azure

image 

Enabling users to download files (blobs) in Windows Azure can be done in 4 ways ;
(as Microsoft evangelist Sean Harris explains in this blogpost)

  • Direct Download – Set the Access of the Container to Public Read Access or Full Public Read Access and expose the URL to the end user. The drawback of this method is obviously security – you have no way of controlling access when the URL is exposed. There is also no way of detecting downloads, and to execute code before/after the download.
     
     
  • API Download – The user must run a Windows App, Silverlight etc. Also – the app must contain the store account name and key – which might compromise security. Especially if you have several customers using the same account (they can still have their own containers of course).
     
     
  • Proxy Download – Have the user access a URL on YOUR server – which then retrieves the file from Azure and sends it to the user. The advantage of this is that you have full control of downloads, you can execute code before/after downloading and you don’t have to expose any Azure URL’s / account info. In fact – the end user will not even see that the file is stored in Azure. You can also override the filename this way.  A downside is that all traffic passes through your server – so you’ might get a bottleneck here.
     
     
  • Pass-through Download (Azure Shared Access Signature) – Creates a signature and inserts this signature in a URL where the user is redirected to Azure. The signature enables the user to access the file for a limited period of time. This is most likely your best option. It enables custom code to be executed before downloading, it will ensure max download speed for your users, and a good level of security is also ensured.

Our client has files stored as Guids in Azure – and we keep track of files (names, sizes etc) and folders in a MS Sql database. This is the reason we have to use the Proxy Download option – when users are downloading files.

Sean Harris has developed such a proxy which streams the file directly from Azure to the end user. This code however requires a third party framework, and seems to overcomplicate things a lot. Here’s a version which does the job just as well (.ashx generic handler):

 

//Retrieve filenname from DB (based on fileid (Guid))
// *SNIP*
string filename = "some file name.txt";

//IE needs URL encoded filename. Important when there are spaces and other non-ansi chars in filename.
if (HttpContext.Current.Request.UserAgent != null && HttpContext.Current.Request.UserAgent.ToUpper().Contains("MSIE"))
    filename = HttpUtility.UrlEncode(filename, System.Text.Encoding.UTF8).Replace("+", " ");

context.Response.Charset = "UTF-8";
//Important to set buffer to false. IIS will download entire blob before passing it on to user if this is not set to false
context.Response.Buffer = false;
context.Response.AddHeader("Content-Disposition", "attachment; filename="" + filename + """);
context.Response.AddHeader("Content-Length", "100122334"); //Set the length the file
context.Response.ContentType = "application/octet-stream";
context.Response.Flush();

//Use the Azure API to stream the blob to the user instantly.
// *SNIP*
fileBlob.DownloadToStream(context.Response.OutputStream);