Is it possible to manipulate .net controls from native code? Particularly, I'd like to set the text of a TextBox from some native code. I want it done this way to keep the business logic separated from the user interface, but it is precisely the native code which only knows how to appropriately format the data (some bytes received within a protocol).
I know I could get the window handle through the Handle property, but once there, how would I call the desired method?
Is string handling my only option? Should the native code build up the message to be displayed on the control?
The "native" way of setting the text on a textbox is to send the textbox the WM_SETTEXT message:
// handle is initialized from TextBox::Handle
PostMessage(handle, WM_SETTEXT, 0, _T("Some text"));
Read up on PostMessage and SendMessage, too. Depending on how you allocate and build up the text, you may need to use SendMessage to avoid deallocating prematurely.
If you want to keep your business logic separated from your user interface, and some of your business logic is in native code, then it would be a really good idea not to change any GUI content from the native code directly, because it is exactly the opposite of what you want to achieve. Better try to write some kind of wrapper method in C++/CLI to call the native data format routine from there, making it available for your use in your GUI code.
If you really want to make calls from native code to managed code, you can declare a (native!) static method in C++/CLI which calls a managed method. You can pass a function pointer to such a method to a lower layer of your program (for example, your native C++ layer), which can be called from there.
Something along the lines of:
// the native code layer:
// "Callbacks.h"
void (*_myNativeCallback)();
void InitCallback(void (*myNativeCallback)())
{
_myNativeCallback=myNativeCallback;
}
// now you can use _myNativeCallback within your native code
// the C++/CLI layer:
#include "Callbacks.h"
//...
static void MyNativeCallback()
{
ManagedClass::StaticMethod();
}
InitCallback(MyNativeCallback);
In ManagedClass::StaticMethod, you have access to your .NET code and you should not have any problems to manipulate a TextBox of any form you can reach from there. If you have to convert a native string to a System::String, you may find this code snippet helpful:
inline System::String StdToSysString(const std::string &s)
{
return gcnew System::String(s.c_str());
}
And the other way round (Ansi code page assumed):
inline std::string SystemToStdString(System::String ss)
{
using namespace System::Runtime::InteropServices;
const char* chars =
(const char*)(Marshal::StringToHGlobalAnsi(ss)).ToPointer();
std::string s = chars;
Marshal::FreeHGlobal(System::IntPtr((void*)chars));
return s;
}
Related
What I'm trying to achieve (more than “to reproduce”):
In other projects (not TUI contexts) I've used several GUI toolkit (wxWidgets, wxPython), etc. (just to name a few)), and most of the time they have handy methods on widgets receiving user input (like “text control” (single and/or multi lines)), methods which are used to get the content of the widgets into any container/object (e.g. string (1)).
Is there any similar functionality in ncurses?
Lets say I have the following code:
WINDOW *textarea = newwin(height, width, starty, startx);
/**
* There, code for letting the user type text in the textarea
**/
switch (ch)
{
case KEY_F(4): // Save
/**
* What do I do from here
* to get all the content of the textarea WINDOW
* that the user typed in
**/
break;
}
Does ncurses provides such a feature?
I'm working on a lightweight terminal text editor (not a source code editor, simply a text editor), and it would greatly simplify my job if I could do such a thing with ncurses.
Notes (for the curious)
(1): For example the wxTextCtrl::GetValue which returns a wxString
curses doesn't have a notion of "containers". It uses windows (whose semantics are defined by the calling application), and can get input characters associated with a window, e.g., using wgetch or wget_wch. The string-input functions call one of those.
However, the input streams for the wgetch/wget_wch functions are probably (unless you set up separate screens) the same input device. It's up to the application to decide how to distinguish input from one or multiple windows.
Say I have two main classes, Application and ApplicationGUI. Application does lots of things and can happily run without any knowledge that ApplicationGUI exists. ApplicationGUI is linked to Application in many ways, it has maybe 50 or 100 different knobs that can change Application's behavior.
ApplicationGUI is a hierarchical structure such that it has many instances of ControlGroup, each containing an arbitrary number of Buttons and Knobs, or even another ControlGroup.
Current design: Upon instantiation of the ApplicationGUI (Application was already running with some set of default parameters), I pass pointers of Application's parameters to various components of the GUI. For example:
my_gui.sound_controlgroup.knob.link_to_param(&(my_application.volume));
If I need to do something more complex, say call a member function of Application, my_application.update_something(), how is this done?
The easy answer is to pass a pointer to my_application to my_gui.sound_controlgroup.knob, but if I only ever need to call one of my_application's functions, it seems like I am giving my knob an option to change all kinds of things that it should even know about (my_application.update_something_unrelated(), for instance). What is the cleanest thing to do in this case?
Additionally, this either requires making all subcomponents of ApplicationGUI public or having a function at each stage of the hierarchy to forward that pointer to the bottom level. This leads to quite a lot of functions. Is this a necessary consequence of a UI with a lot of knobs?
Quick Short Answer
In order to implement interaction between your non GUI related Application object and your GUIApplication object I suggest apply the "Property and Method and Event Handler" paradigm.
Extended Complex Answer
G.U.I. development is one of the most practical implementation of the O.O.P. theory.
What is the "Property and Method and Event Handler" paradigm ?
That means build, both Non GUI Classes, and GUI Classes, should have:
Properties
Methods
Event handlers
"Events" (Handlers) are also called "Signals", and are implemented with functions pointers. Not sure, but, I think your "knob" (s) are like Event Handlers.
It's a technique to apply the my_application.update_something_unrelated(), you have in your question.
Since, C++, like Java, does not have property syntax, you may use "getter" and "setter" methods, or use a "property" template.
For example, if your application has a Close method, you may declare something like the following examples.
Note: They are not full programs, just an idea:
// Applications.hpp
public class BaseApplicationClass
{
// ...
};
public class BaseApplicationClientClass
{
// ...
};
typedef
void (BaseApplicationClientClass::*CloseFunctor)
(BaseApplicationClass App);
public class ApplicationClass: public BaseApplicationClass
{
// ...
public:
Vector<BaseApplicationClientClass::CloseFunctor>
BeforeCloseEventHandlers;
Vector<BaseApplicationClientClass::CloseFunctor>
AfterCloseEventHandlers;
protected:
void ConfirmedClose();
public:
virtual void Close();
} Application;
// Applications.cpp
void ApplicationClass::ConfirmedClose()
{
// do close app. without releasing from memory yet.
} // void ApplicationClass::ConfirmedClose()
void ApplicationClass::Close()
{
// Execute all handlers in "BeforeCloseEventaHandlers"
this.ConfirmedClose();
// Execute all handlers in "AfterCloseEventaHandlers"
} // void ApplicationClass::Close()
// AppShells.cpp
public class AppShell: public BaseApplicationClientClass
{
// ...
};
void AppShell::CloseHandler(ApplicationClass App)
{
// close GUI
} // void AppShell.CloseHandler(ApplicationClass App)
void AppShell::setApp(ApplicationClass App)
{
App->BeforeCloseEventHandlers->add(&this.CloseHandler);
} // void AppShell.setApp(ApplicationClass App)
void main (...)
{
ApplicationClass* AppKernel = new ApplicationClass();
ApplicationGUIClass* AppShell = new ApplicationGUIClass();
AppShell.setApp(App);
// this executes "App->Run();"
AppShell->Run();
free AppShell();
free AppKernel();
}
UPDATE: Fixed type declaration from global function pointer (a.k.a. "global functor") to object function pointer (a.k.a. "method functor").
Cheers.
Do you know about the model-view-controller (MVC) paradigm? Think of the Application class as the model, the entire hierarchy of GUI controls as the view, and the ApplicationGUI class as the controller. You don't want Application to know about the controls, and you don't want the controls to know about Application; they should both talk only to the controller, ApplicationGUI.
Using ApplicationGUI as the conduit for communication between controls and Application means that you can test either Application or controls by replacing the other with a mock object, for example. More importantly, you can change either the controls or Application without impacting the other. Individual controls don't need to know anything about Application -- they only need to know where to send their value when it changes. And Application shouldn't care whether an input comes from a knob or a slider or a text field. Keeping those two areas separate will simplify each of them.
Additionally, this either requires making all subcomponents of
ApplicationGUI public or having a function at each stage of the
hierarchy to forward that pointer to the bottom level. This leads to
quite a lot of functions. Is this a necessary consequence of a UI with
a lot of knobs?
A given control shouldn't care what value it manages. It doesn't need to know whether the value determines the number of alien invaders on the screen or the coolant level in a nuclear reactor. It does needs to know things like the minimum and maximum values, label to display, scale to use (linear, log, etc.), and other things that directly impact the way the control works. It also needs to know who to tell when something changes, and it might need some way to identify itself.
With that in mind, ApplicationGUI doesn't need to expose accessors for every possible parameter of Application. Instead, it should have a general method that lets controls send it updates. When a control changes, it should send a message to ApplicationGUI containing the new value(s) along with its identifier, and ApplicationGUI takes care of mapping that identifier to some particular parameter of Application. A control's identifier could be some identifying number that's given to it, or it could just be a pointer to the control.
Of course, sometimes communication has to go the other way, too... a GUI usually has both inputs and outputs, so you'll want some means for ApplicationGUI to get updates from Application and update the state of the GUI. For the same reasons described above, Application should send those updates to ApplicationGUI and let the latter find the actual UI components that need to be changed.
I want to show a message to user when the user changes the language keyboard layout of Windows for example from EN to FR. But I don't know how can I be informed when the user changes it using either the taskbar or ALT+SHIFT. Which win32api function should I use?
I need something like this pseudocode :
void inputLanguageChanged(char *ln)
{
message("You selected " + ln + " language");
}
The traditional way of doing this was to handle the WM_INPUTLANGCHANGE message. But there are a couple of problems with this method:
it is only sent to the active (focused) window, and
it doesn't catch all possible cases, and may not be reliable on modern versions of Windows.
The better solution, then, is to implement the ITfLanguageProfileNotifySink interface, whose OnLanguageChanged method is called whenever the input language changes, regardless of the way that it was changed.
However, I see that your question is tagged with both the C and C++ tags. You can use COM from C, but it's a real pain in the neck. Far simpler if you're using C++. If I needed to do this work in a C program, I'd probably just find a way to make WM_INPUTLANGCHANGE work for me. Maybe I'm just lazy.
You can use WM_INPUTLANGCHANGE message:
case WM_INPUTLANGCHANGE:
{
HKL hkl = (HKL)lParam;
WCHAR localeName[LOCALE_NAME_MAX_LENGTH];
LCIDToLocaleName(MAKELCID(LOWORD(hkl), SORT_DEFAULT), localeName, LOCALE_NAME_MAX_LENGTH, 0);
WCHAR lang[9];
GetLocaleInfoEx(localeName, LOCALE_SISO639LANGNAME2, lang, 9);
}
https://learn.microsoft.com/windows/win32/intl/locale-names
https://learn.microsoft.com/windows/win32/intl/nls--name-based-apis-sample
I have an old legecy ATL/MFC application with two threads, the main Window-Thread and a Render-Thread. My problem is I have random, access-violation errors related to a CSimpleString; i.e. access violation, 0xdddddddd etc...
I have deduced the problem is the two threads accessing the same string at the same time, one trying to use it to render (the MFC main Window-Thread) and one trying to update the string (the Render-Thread).
From the MFC side; the class is
class CDisplay : public CStatic
{
public:
CString m_strDisplay;
...
void SetDisplay(CString str, int nMode = -1);
...
}
There is no paint override and the text is basically rendered via CStatic.
Now, the SetDisplay method is what is called from the Render-Thread; and it prodominent code is:
if (m_strDisplay != str)
{
m_strDisplay = str;
SetWindowText(str + " ");
}
My problem here, is that I need a critical section; but I don't know how to get the MFC side to adhere to it.
Anyone have some wisdom in making MFC thread-safe and avoiding these problems?
Make GUI updates (SetWindowText) in the MFC main thread only. In the render thread, set a variable (protected by critical section) and/or send a message, and then perform the actual GUI element manipulation in the MFC main thread.
I have some code which shows a simple dialog box and handles user action (written using plain WinAPI).
// Display dialog and handle user action
LRESULT choice = DialogBoxParam(NULL, MAKEINTRESOURCE(AP_IDD_DIALOG), NULL, (DLGPROC)DialogCallback, NULL);
Is there any way to hardcode the resource file dialog.rc, which is used to build the dialog ?(I would like to get rid of .rc files and I'm pretty sure there is a way, yet I don't know what it is :)
Edit
Also, does someone have any ideas on converting existing .rc files into hardcoded resources? Is this possible?
*.rc (resource) files are source code, they are compiled with the resource compiler and linked into your object (.exe/.dll)
You don't need to ship the resource file or have it present with your app to run it.
If you want to move to programmatically defined windows rather than templates then you might want to be looking at QT/wxWidgets. But thats a fair chunk of overhead for 1 dialog!
I'm surprised I couldn't find an existing app to do this sort of thing, enough hits on google with people trying to do this.
Ok, so the DLGTEMPLATE is a variable length blob of data, normally you let the dialog function pull it from the resource bundle for you, but instead you want to store it in your program.
You need to change your static lib to have a new function to decode some 'blob' back into the dlgtemplate, and you need to generate the blob. (or add the blob in your code without decoding which I don't want to think about right now)
The following code will give you the DLGTemplate data you need to imbed in your app. (cut from larger project)
HGLOBAL LoadResourceImpl(wchar_t *resource, wchar_t *type)
{
HRSRC handle = FindResource(hInstance, resource,type);
if (handle)
{
HGLOBAL hResource = LoadResource(hInstance, handle);
if (hResource)
return LockResource(hResource);
}
return 0;
}
DLGTEMPLATE * LoadDialog(wchar_t *resource)
{
return (DLGTEMPLATE *) LoadResourceImpl(resource,RT_DIALOG);
}
DLGTEMPLATE * LoadDialog(int resource)
{
return (DLGTEMPLATE *) LoadResourceImpl(MAKEINTRESOURCE(resource),RT_DIALOG);
}
Make an app that includes your resource - use the appropriate LoadDialog to get the data.
Now "write out" that blob in a format to include in your app -
step 1 - find out how much data there is by traversing the structure to find the total size including all the controls (control count is in DLGTEMPLATE::cdit)
step 2 - convert the data to something you can compile into your code - like HEX
Add to your static library a new 'HEX' to DLGTEMPLATE method and the hex string you made using the other app.
Can we hard code the .res file into the program?
the resource compiler converts .rc into .res
use a hex dump tool (eg. winhex) to translate the .res into bytes array
(represented in C source code).
add the source code file in the project and compile in the executable.
locate the dialog resource position from the array and use DialogBoxIndirect.
DialogBoxParamIndirect can be used instead. It takes as a parameter the dialog template. Raymond Chen's blog has an example of building a dialog box at runtime rather than from a resource using the DialogBox*Indirect API's.
Per MSDN, dialog box resources are basically composed of the DLGTEMPLATE and DLGITEMTEMPLATE structures. So you should be able to use the resource API's (FindResource, LoadResource, and LockResource) to get at the underlying bits of an existing dialog resource, and embed that within your code.
Note that this is a lot more painful than using the .rc file. It's much more difficult to make changes to your layout, and it's also much less localizable, since localization would now require a code change to update the template in code.
If it's a simple dialog, why use the DLGTEMPLATE at all?
Nothing stops you from simply doing ::CreateWindow'ing those controls directly. If it's a simple dialog with 2-3 buttons and a couple text fields, simply call ::CreateWindow, passing in the window class of whatever common control you're using.
This is essentially what the DialogXxxxx functions do anyway. DLGTEMPLATE is a convenience for declaratively laying out your forms, and having the boilerplate make the appropriate CreateWindow calls, etc.