C++/CLI Timer freezes applications - winforms

I am using a timer in a c++ windows form app. To handle receiving messages sent from a server using WinSock2. The current code for my timer is,
private: System::Void tmrMessages_Tick(System::Object^ sender, System::EventArgs^ e) {
int ID;
char* cID = new char[64];
char* message = new char[256];
ZeroMemory(cID, 64);
ZeroMemory(message, 256);
if(recv(sConnect, message, 256, NULL) != SOCKET_ERROR && recv(sConnect, cID, 64, NULL) != SOCKET_ERROR)
{
ID = atoi(cID);
if (ID == 1)
{
lbxMessages->Items->Add("hello");
}
}
}
I didn't have it add the variables to the listbox because I wanted to test and make sure it worked first. It DOES work but, it makes the app so slow that it doesn't allow any user input at all. It does show the listbox being updated but, like I said doesn't allow me to move the window, click textboxes or anything. If you have any idea why this is happening please let me know.
thanks.

If those are blocking reads, they'll freeze the UI thread until you get data.
What you should do is set non-blocking mode and read until you fill your buffer, which may take multiple recv calls, the process it.
I really like WSAAsyncSelect for this... it automatically puts the socket into non-blocking mode and sends your window a message whenever data is available. You can easily handle that message by overriding WndProc.
It should be pretty straightforward:
#include <winsock2.h>
#include <windows.h>
const unsigned WM_SOCKETREADY = WM_USER + 100;
...
when you open the socket (assuming that's a member function of the form), call
WSAAsyncSelect(sConnect, HWND(Handle.ToPointer()), WM_SOCKETREADY, FD_READ);
and then WndProc (which you should override) will have the message delivered to it
virtual void WndProc( Message% m ) override
{
switch (m.Msg) {
case WM_SOCKETREADY:
ReadSocketHandler();
return;
default:
Form::WndProc(m);
return;
}
}

Related

Get receive keyboard an mouse events from SDL2 in WPF application

I'm trying to capture mouse and keyboard events from SDL2 using the SDL2-CS binding library. The events are polled for but these events are never raised.
I think this is because the polling needs to happen on the UI thread. I tried initializing SDL from the UI thread by calling App.Current.Dispatcher.Invoke(Init) but no events are polled.
Basic implementation of my class:
public override void Initialize()
{
if (hooked)
{
return;
}
App.Current.Dispatcher.Invoke(Init); //Run on the UI thread
}
private void Init()
{
var init = SDL.SDL_Init(SDL.SDL_INIT_VIDEO);
if (init != 0)
{
throw new Exception("Could not initialize SDL");
}
hooked = true;
ListenForEvents();
}
private void ListenForEvents()
{
SDL.SDL_Event ev;
while (true)
{
if (SDL.SDL_PollEvent(out ev) != 1) //This is continuously trigged
{
continue;
}
switch (ev.type) //This is never reached
{
case SDL.SDL_EventType.SDL_MOUSEMOTION:
if (MouseMoved != null) { MouseMoved(this, ev.motion); }
break;
...
}
}
}
I'm wondring if I'm invoking the Init on the UI thread wrong, or if the SDL initialization is wrong.
P.S. Hooking with user32.dll is not desired because this code will run on non windows environments as well.
Looking at your code I would say your UI is blocked because ListenForEvents is not running on a different thread and invoking the Init call will run the method - that never returns - on the UI thread.
It might be a good idea to call Init invoked, but then you should start a new thread for polling.

XCB: window will not unmap after being mapped once

I have a small example program written in C that opens a window using the XCB API.
Strictly AFTER I have created and shown the window, I would (at a later time) like to hide the window.
(Obviously in this specific example, I could remove the call to xcb_map_window, and the window would be hidden, but I want to do it at a later point in my larger application, like a toggle to show/hide the window, NOTE: I do NOT want to minimize it).
Here is the sample code (NOTE: this code now works thanks to the answer):
#include <unistd.h>
#include <stdio.h>
#include <stdbool.h>
#include <xcb/xcb.h>
void set_window_visible(xcb_connection_t* c, xcb_window_t win, bool visible) {
xcb_generic_event_t *event;
if(visible) {
// Map the window on the screen
xcb_map_window (c, win);
// Make sure the map window command is sent
xcb_flush(c);
// Wait for EXPOSE event.
//
// TODO: add timeout in-case X server does not ever send the expose event.
while(event = xcb_wait_for_event(c)) {
bool gotExpose = false;
switch(event->response_type & ~0x80) {
case XCB_EXPOSE:
gotExpose = true;
break;
default:
break; // We don't know the event type, then.
}
free(event);
if(gotExpose) {
break;
}
}
} else {
// Hide the window
xcb_unmap_window(c, win);
// Make sure the unmap window command is sent
xcb_flush(c);
}
}
int main() {
xcb_connection_t *c;
xcb_screen_t *screen;
xcb_window_t win;
xcb_generic_event_t *event;
// Open the connection to the X server
c = xcb_connect (NULL, NULL);
// Get the first screen
screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
// Ask for our window's Id
win = xcb_generate_id(c);
// Create the window
uint32_t mask = XCB_CW_EVENT_MASK;
uint32_t valwin[] = {XCB_EVENT_MASK_EXPOSURE | XCB_BUTTON_PRESS};
xcb_create_window(
c, // Connection
XCB_COPY_FROM_PARENT, // depth (same as root)
win, // window Id
screen->root, // parent window
0, 0, // x, y
150, 150, // width, height
10, // border_width
XCB_WINDOW_CLASS_INPUT_OUTPUT, // class
screen->root_visual, // visual
mask, valwin // masks
);
bool visible = true;
set_window_visible(c, win, true);
while(1) {
sleep(2);
// Toggle visibility
visible = !visible;
set_window_visible(c, win, visible);
printf("Window visible: ");
if(visible) {
printf("true.\n");
} else {
printf("false.\n");
}
}
// pause until Ctrl-C
pause();
return 0;
}
Which I compile and run with:
gcc xcbwindow.c -o xcbwindow -lxcb
./xcbwindow
From anything I can find on Google or here, I am doing everything correctly. So for clarification I am using Unity and Ubuntu 12.04 LTS:
unity --version reports:
unity 5.20.0
uname -a reports:
Linux [redacted] 3.2.0-32-generic #51-Ubuntu SMP Wed Sep 26 21:33:09 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
Can anyone explain where I've gone wrong in this code?
EDIT: updated code with a flush() at the end after xcb_unmap_window(); still doesn't work.
EDIT2: Tried code with cinnamon WM; still doesn't work (It's not a Unity bug).
EDIT3: Code updated in this post now works.
Your program simply goes too fast.
It maps the window and then immediately unmaps it. The window is top level, which means the requests are redirected to the window manager. But the window manager receives the unmap request when the window is not mapped yet, so it simply discards the request. Insert sleep(3) between the map and unmap calls and observe.
In real code, your window needs to get at least one expose event before sending out the unmap request. This guarantees it's actually mapped by the window manager.

Dispatching events into right thread

I have developed a wrapper for a library that uses a callback to notify events. This callback is called using another thread than UI's thread, so the wrapper uses the following script to call the event handlers into the right thread for a WinForm application.
void AoComm::Utiles::Managed::DispatchEvent( Delegate^ ev, Object^ sender, Object^ args )
{
ComponentModel::ISynchronizeInvoke^ si;
array<Delegate^>^ handlers;
if(ev != nullptr)
{
handlers= ev->GetInvocationList();
for(int i = 0; i < handlers->Length; ++i)
{
// target implements ISynchronizeInvoke?
si = dynamic_cast<ComponentModel::ISynchronizeInvoke^>(handlers[i]->Target);
try{
if(si != nullptr && si->InvokeRequired)
{
IAsyncResult^ res = si->BeginInvoke(handlers[i], gcnew array<Object^>{sender, args});
si->EndInvoke(res);
}else{
Delegate^ del = handlers[i];
del->Method->Invoke( del->Target, gcnew array<Object^>{sender, args} );
}
}catch(System::Reflection::TargetException^ e){
Exception^ innerException;
if (e->InnerException != nullptr)
{
innerException = e->InnerException;
}else{
innerException = e;
}
Threading::ThreadStart^ savestack = (Threading::ThreadStart^) Delegate::CreateDelegate(Threading::ThreadStart::typeid, innerException, "InternalPreserveStackTrace", false, false);
if(savestack != nullptr) savestack();
throw innerException;// -- now we can re-throw without trashing the stack
}
}
}
}
This code works pretty well, but I have read about Dispatcher class for WPF that do the same than my code (and more, of course).
So, is there something (class, mechanism, ...) equivalent to Dispatcher class for WinForms?
Thanks.
Right, this isn't the right way to do it. Winforms and WPF have different synchronization providers, they install theirs in System::Threading::SynchronizationContext::Current.
To use it, copy the Current value in your constructor. When you are ready to fire the event, check if it is nullptr. If it was then your object got constructed in a worker thread and you should fire your event directly. If it isn't then use the Post() method to run a helper method on the UI thread. Have that helper method fire the event.

X11 Wait for and Get Clipboard Text

I have to monitor the X11 Clipboard.
For the moment, I request the ClipBoard Selection each 5 seconds, then I hash the text returned from clipboard and I compare it with the hash calculate from the last check. If hash are not the same, I analysis the text content and do some stuff...
I don't like my method. I'm from Windows, and with the winapi, it is the kernel that notify your program when the clipboard has changed, and it's more efficient!
I just want to know if it is possible that X11 can notify your program as winapi when the clipboard has changed ? What is the more efficient way to check clipboard modifications with X11 ?
Use XFixesSelectSelectionInput() from Xfixes extension and wait for XFixesSelectionNotify event.
Example:
// gcc -o xclipwatch xclipwatch.c -lX11 -lXfixes
...
#include <X11/extensions/Xfixes.h>
...
void WatchSelection(Display *display, Window window, const char *bufname)
{
int event_base, error_base;
XEvent event;
Atom bufid = XInternAtom(display, bufname, False);
assert( XFixesQueryExtension(display, &event_base, &error_base) );
XFixesSelectSelectionInput(display, DefaultRootWindow(display), bufid, XFixesSetSelectionOwnerNotifyMask);
while (True)
{
XNextEvent(display, &event);
if (event.type == event_base + XFixesSelectionNotify &&
((XFixesSelectionNotifyEvent*)&event)->selection == bufid)
{
if (!PrintSelection(display, window, bufname, "UTF8_STRING"))
PrintSelection(display, window, bufname, "STRING");
fflush(stdout);
}
}
}
...
This works both for bufname == "CLIPBOARD" and bufname == "PRIMARY" selection.
Also see PrintSelection() function in this answer.
Find window with selection using GetSelectionOwner (PRIMARY and CLIPBOARD)
get copy of selection by sending SelectionRequest, notify your application
watch for SelectionClear event
update window with selection using id from SelectionClear event, goto step 2
The accepted answer from x11user is a good one. But you probably want a non-blocking while loop, and for that you can take that answer, and adapt it like this.
// get the internal X11 event file descriptor
int x11fd = ConnectionNumber(display);
while(!shutdown)
{
if(!XPending(display)) {
// wait on the file descriptor
// you can use poll, epoll, select, eventfd, etc.
}
XNextEvent(display, &event);
// process the event
}

C# Winforms: BeginInvoke still running on same thread?

I'm web developer and I'm trying to step into multithreading programming.
On one form I'm trying to run a method computing values in a second thread using asynchronous delegates.
I also want a progress bar showing actual progress in UI thread been notified.
delegate void ShowProgressDelegate(int total, int value);
delegate void ComputeDelegate(int value);
//Some method simulating sophisticated computing process
private void Compute(int value)
{
ShowProgress(value, 0);
for (int i = 0; i <= value; i++)
{
ShowProgress(value, i);
}
}
//Method returning values into UI thread
private void ShowProgress(int total, int value)
{
if (!this.InvokeRequired)
{
ComputeButton.Text = value.ToString();
ProgressBar.Maximum = total;
ProgressBar.Value = value;
}
else
{
ShowProgressDelegate showDel = new ShowProgressDelegate(ShowProgress);
this.BeginInvoke(showDel, new object[] { total, value });
}
}
//firing all process
private void ComputeButton_Click(object sender, EventArgs e)
{
ComputeButton.Text = "0";
ComputeDelegate compDel = new ComputeDelegate(Compute);
compDel.BeginInvoke(100000, null, null);
}
When I run this, everything is computing without any problem except it is still running in UI thread (I suppose so, because it freezes when I click some button on the form).
Why? I also attach buildable sample project (VS2010) with same code: http://osmera.com/windowsformsapplication1.zip
Thanks for helping neewbie.
In the code you've shown, you're doing nothing other than updating the progress bar - so there are thousands of UI messages to marshal, but nothing significant happening in the non-UI thread.
If you start simulating real work in Compute, you'll see it behave more reasonably, I suspect. You need to make sure you don't swamp the UI thread with progress updates like you are doing now.

Resources