Custom Dialogs
FAQ about UI and .Net
If existing Syrve POS dialogs are not enough, the plugin can show user-defined dialogs, however, certain specifics should be taken into account.
First, the plugin default host process does not include the STA thread. required for the UI. Though the plugin must create it. Sample code:
ctor()
{
var windowThread = new Thread(EntryPoint);
windowThread.SetApartmentState(ApartmentState.STA);
windowThread.Start();
}
...
private void EntryPoint()
{
Window window = new MyWindow();
window.ShowDialog();
}
Second, by default, a background process dialog has no focus, therefore, input events pertain to the previously active dialog, i.e. Syrve POS dialog. According to Microsoft, the app cannot be foreground on its own, it’s only the previously active dialog that can do it, or it is the user who can foreground the app. However, the latter can be pre-programmed:
public static void ClickWindow(Window wnd)
{
try
{
var wih = new WindowInteropHelper(wnd);
WinApi.RECT rect;
WinApi.GetWindowRect(new HandleRef(wnd, wih.Handle), out rect);
var x = rect.Left + (rect.Right - rect.Left) / 2;
var y = rect.Top + (rect.Bottom - rect.Top) / 4;
WinApi.LeftMouseClick(x, y);
}
catch (Exception) { }
}
Third, the plugin dialog, being an independent window, can be put behind the Syrve POS window. The Always On Top mode cannot solve the issue, as other topmost windows can be present, including the Syrve POS app itself. The plugin can link its dialog to the Syrve POS window as a child dialog via the SetParent
WinAPI function. Although the Syrve POS window hwnd is not published in the API, the plugin can find it on its own.