I am writing a windows app using wxWidghets on visual studio and plan to go build it for linux when this is up and running well on windows.
I have a search control on the main control which I have attached a search on Enter key function on it but it is not doing anything and I cant figure out what I have not done or what else I should do to make it work when the user will press enter on the control.
myframe.h
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/string.h>
#include <wx/srchctrl.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/frame.h>
class MyFrame : public wxFrame
{
private:
protected:
wxSearchCtrl* TxtSearch;
void OnSearchButton( wxCommandEvent& event );
void OnSearchEnter( wxCommandEvent& event );
public:
MyFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,300 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
~MyFrame();
};
myframe.cpp
#include "myframe.h"
MyFrame::MyFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* bSizer1;
bSizer1 = new wxBoxSizer( wxVERTICAL );
TxtSearch = new wxSearchCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
#ifndef __WXMAC__
TxtSearch->ShowSearchButton( true );
#endif
TxtSearch->ShowCancelButton( false );
bSizer1->Add( TxtSearch, 1, wxALL|wxEXPAND, 5 );
wxStaticBoxSizer* sbSizer1;
sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxT("label") ), wxVERTICAL );
bSizer1->Add( sbSizer1, 1, wxALL|wxEXPAND, 5 );
this->SetSizer( bSizer1 );
this->Layout();
this->Centre( wxBOTH );
// Connect Events
TxtSearch->Connect( wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN, wxCommandEventHandler( MyFrame::OnSearchButton ), NULL, this );
TxtSearch->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( MyFrame::OnSearchEnter ), NULL, this );
}
MyFrame::~MyFrame()
{
// Disconnect Events
TxtSearch->Disconnect( wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN, wxCommandEventHandler( MyFrame::OnSearchButton ), NULL, this );
TxtSearch->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( MyFrame::OnSearchEnter ), NULL, this );
}
MyFrame::OnSearchButton()
{
SetStatus("You pressed search button");
}
MyFrame::OnSearchEnter()
{
SetStatus("You pressed enter");
}
the other event for pressing the search button actually works something which I cant fail to understand at the moment. Online when I search I am just seeing more documentation on wxPython and I just cant what speaks for c++. I would appreciate some enlightment on this
According to official wxSearchCtrl docs you should handle the wxEVT_SEARCH event, which is fired both when the search button is clicked and when Enter is pressed in the control.
And also, there's nothing wrong with using Connect(), but it's better to use Bind(), see docs.
So putting it all together:
MyFrame::MyFrame(.....)
// Connect Events
//TxtSearch->Connect( wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN, wxCommandEventHandler( MyFrame::OnSearchButton ), NULL, this );
//TxtSearch->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( MyFrame::OnSearchEnter ), NULL, this );
TxtSearch->Bind( wxEVT_SEARCH, &MyFrame::OnSearchButton, this );
....
//Not required but here it is:
MyFrame::~MyFrame(....)
TxtSearch->Unbind( wxEVT_SEARCH, &MyFrame::OnSearchButton );
#Ripi2's answer is okay but may fail to fire the event as the OP asked. I think you need to look at how you create the wxSearchCtrl and see if you are initiating the search event properly.
Change it from:
TxtSearch = new wxSearchCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
To this:
TxtSearch = new wxSearchCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
Let me know if this works, since I have not tested it myself.
Related
When my source is grabbing the stream, the callback function is called and I have the wxMessageBox("Got buffer"); which display the text Got Buffer. But At this point I don't know how to have the information in my main code that my stream is actually grabing something and so I can display it (I want to sure that my pipeline is grabbing something before asking for display). For example, changing my toolbar icon that indicate the user that the pipeline is actually grabbing something and he can display it. you can find my code bellow :
#include "MainWindow.h"
wxBEGIN_EVENT_TABLE(MainWindow, wxFrame)
EVT_TOOL(10001, LoadVideo)
wxEND_EVENT_TABLE()
MainWindow::MainWindow(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxPoint(30, 30), wxSize(1224, 1024))
{
wxInitAllImageHandlers();
wxBitmap load(wxT("bitmap.png"), wxBITMAP_TYPE_PNG);
wxPanel* bg = new wxPanel(this, wxID_ANY);
bg->SetBackgroundColour(wxColor(230, 230, 230));
m_renderWindow = new wxWindow(bg, wxID_ANY);
m_renderWindow->SetBackgroundColour(*wxBLACK);
// Layout the UI.
wxBoxSizer* szr1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* szr2 = new wxBoxSizer(wxHORIZONTAL);
szr1->Add(m_renderWindow, wxSizerFlags(1).Expand().Border(wxBOTTOM));
szr1->Add(szr2, wxSizerFlags(0));
bg->SetSizer(szr1);
toolbar->AddTool(10001, _T("ContinuousShot"), load);
toolbar->Realize();
Layout();
// Set up the event handlers.
#ifdef __WXGTK__
m_renderWindow->Bind(wxEVT_CREATE, &MainWindow::OnRendererWinCreated, this);
#endif
// Initialize GStreamer.
m_xid = 0;
m_pipeline = NULL;
gst_init(NULL, NULL);
}
GstPadProbeReturn buffer_out_cb(GstPad* pad, GstPadProbeInfo* info, gpointer user_data)
{
GstElement* pipe = (GstElement*)user_data;
//toolbar->SetToolNormalBitmap(10001, wxBitmap(wxT(icon-open-device.png), wxBITMAP_TYPE_PNG));
wxMessageBox("Got buffer");
gst_element_set_state(pipe, GST_STATE_PAUSED);
//remove the probe if you don't need it anymore, otherwise return GST_PAD_PROBE_OK
return GST_PAD_PROBE_REMOVE;
}
void MainWindow::LoadVideo(wxWindowCreateEvent&)
{
GstPad* pad;
GError* error = NULL;
//GstElement* pipeline;
GstElement* source;
GstCaps* caps = gst_caps_new_simple("application/x-rtp",
"media", G_TYPE_STRING, "video",
"payload", G_TYPE_INT, 96,
"encoding-name", G_TYPE_STRING, "H264",
NULL);
m_pipeline = gst_parse_launch("udpsrc name=source !rtpjitterbuffer !rtph264depay !h264parse !avdec_h264 !autovideoconvert !d3dvideosink name=mysink sync=false ", &error);
if (!m_pipeline) {
g_print("Parse error: %s\n", error->message);
exit(1);
}
source = gst_bin_get_by_name(GST_BIN(m_pipeline), "source");
g_object_set(G_OBJECT(source), "caps", caps, NULL);
g_object_set(G_OBJECT(source), "port", m_port, NULL);
pad = gst_element_get_static_pad(source, "src");
gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, (GstPadProbeCallback)buffer_out_cb, m_pipeline, NULL);
gst_object_unref(pad);
#ifdef __WXGTK__
GstElement* sink = gst_bin_get_by_name((GstBin*)m_pipeline, "mysink");
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(sink), m_xid);
#elif defined __WXMSW__
GstElement* sink = gst_bin_get_by_name((GstBin*)m_pipeline, "mysink");
WXWidget hwnd = m_renderWindow->GetHandle();
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(sink),
reinterpret_cast<guintptr>(hwnd));
#endif
gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
}
The solution :
pass a pointer in the callback function (gpointer user_data), for example a int that is at 0 if the callback is not called and at 1 if it is called
If I put the WNDCLASSEX wcex variable definition out of main function (as global variable) the class will be registered successfully
#include <windows.h>
WNDCLASSEX wcex;
int main()
{
wcex.cbSize = sizeof ( WNDCLASSEX );
wcex.lpszClassName = "Success" ;
if ( !RegisterClassEx ( &wcex ) )
{
MessageBox ( NULL, "Failed to register window class.", "Error", MB_OK );
}
}
But If I put it inside the main function, It will not be registered
#include <windows.h>
int main()
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof ( WNDCLASSEX );
wcex.lpszClassName = "Success" ;
if ( !RegisterClassEx ( &wcex ) )
{
MessageBox ( NULL, "Failed to register window class.", "Error", MB_OK );
}
}
I can't figure out the reason, kindly help in this issue.
Thanks in advance.
Objects with static storage duration are zero-initialized1). Your second example is semantically different in that wcex (automatic storage duration) holds random values. To match the semantics, use WNDCLASSEX wcex = { 0 }; instead.
1) Assuming you are using a C++ compiler. The rules for C are different.
I try to write kiosk web browser and run it automaticly after system boot. It's simple GTK2+ application, with WebKit used as browser.
It starts from ~/.xinitrc:
exec /home/kiosk-user/bin/browser 'http://localhost/'
Source code browser.c:
#include <stdio.h>
#include <signal.h>
#include <stdio.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
#include <webkit/webkit.h>
int main( int argc, char* argv[] ) {
WebKitWebView* web_view;
GtkWidget* window;
GtkWidget* scrollable_content;
if( argc < 2 ) {
fprintf( stderr, "The first argument have to be URI" );
return 1;
}
gchar* uri = argv[1];
gtk_init( &argc, &argv );
gint
screen_width = gdk_screen_width(),
screen_height = gdk_screen_height();
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
scrollable_content = gtk_scrolled_window_new( NULL, NULL );
gtk_window_set_default_size( GTK_WINDOW( window ), screen_width, screen_height );
web_view = WEBKIT_WEB_VIEW( webkit_web_view_new() );
gtk_container_add( GTK_CONTAINER( scrollable_content ), GTK_WIDGET( web_view ) );
gtk_container_add( GTK_CONTAINER( window ), scrollable_content );
GdkCursor* cursor = gdk_cursor_new( GDK_ARROW );
gdk_window_set_cursor( window->window, cursor );
webkit_web_view_load_uri( web_view, uri );
gtk_widget_show_all( window );
gtk_main();
return 0;
}
The problem is cursor, it's not showing on application start, until I will click somewhere. When it will appear, it looks good on text input, links etc. but when I move from that kind of element, it changes appeariance to GDK_X_CURSOR(screenshot) instead of default arrow. Running it from desktop manager displays cursor properly.
On web page cursor is default.
Testing on: Virtual Machine => Debian GNU/Linux 8.1 (jessie)
Thank you in advance for your help and sorry if my English is not good enough.
You can find solution here. Just put xsetroot -cursor_name left_ptr in your ~/.xinitrc.
So I'm sending key presses to another application, like so:
- (void)keyPress:(int)hotkey withModifier:(unsigned int)modifier withKeyDown:(BOOL)keyDown{
// verify the process still exists
ProcessSerialNumber psn = [self myPSN];
CGEventRef keyEvent = NULL;
// create our source
CGEventSourceRef source = NULL; // this didn't used to be NULL, does this matter?
if ( source || 1 == 1 ){
keyEvent = CGEventCreateKeyboardEvent(source, (CGKeyCode)hotkey, keyDown);
// set flags for the event (does this even matter? No.)
CGEventSetFlags( keyEvent, modifier );
// hit any specified modifier keys
if ( modifier & NSAlternateKeyMask ){
PostKeyboardEvent( source, kVK_Option, keyDown );
}
if ( modifier & NSShiftKeyMask ){
PostKeyboardEvent( source, kVK_Shift, keyDown );
}
if ( modifier & NSControlKeyMask ){
PostKeyboardEvent( source, kVK_Control, keyDown );
}
if ( modifier & NSCommandKeyMask ){
PostKeyboardEvent( source, kVK_Command, keyDown );
}
// post the actual event
CGEventPostToPSN(&psn, keyEvent);
usleep(30000);
// post it again if we're doing key up, just in case!
if ( !keyDown ){
CGEventPostToPSN(&psn, keyEvent);
}
// release
if ( keyEvent ){
CFRelease(keyEvent);
}
}
}
Basically, I can send keys FINE if they are using a US Keyboard, such as sending: kVK_ANSI_A
The problem is with non-US keyboards, how can I adapt these keys to still send correctly if the keyboard layout is NOT set to US?
Here are the virtual key codes I'm having trouble with: http://pastebin.com/qXnXHb5M
Thanks in advance!
I think its the same question as How to convert ASCII character to CGKeyCode?
I'm developing a COM dll which is an add-in to MSoffice. Since I'm not creating any logs within add-in I would like to add a crash report generator into my add-in.
Hopefully 'Minidump' would be the best choice, but I have never use Minidump inside a COM object.
I appreciate if somebody can point out possibilities of creating such crash dump with minidump
inside a COM object.
Thank You
I suspect you should be able to use the technique described here, create a minidump.
The actual implementation is
straightforward. The following is a
simple example of how to use
MiniDumpWriteDump.
#include <dbghelp.h>
#include <shellapi.h>
#include <shlobj.h>
int GenerateDump(EXCEPTION_POINTERS* pExceptionPointers)
{
BOOL bMiniDumpSuccessful;
WCHAR szPath[MAX_PATH];
WCHAR szFileName[MAX_PATH];
WCHAR* szAppName = L"AppName";
WCHAR* szVersion = L"v1.0";
DWORD dwBufferSize = MAX_PATH;
HANDLE hDumpFile;
SYSTEMTIME stLocalTime;
MINIDUMP_EXCEPTION_INFORMATION ExpParam;
GetLocalTime( &stLocalTime );
GetTempPath( dwBufferSize, szPath );
StringCchPrintf( szFileName, MAX_PATH, L"%s%s", szPath, szAppName );
CreateDirectory( szFileName, NULL );
StringCchPrintf( szFileName, MAX_PATH, L"%s%s\\%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp",
szPath, szAppName, szVersion,
stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,
GetCurrentProcessId(), GetCurrentThreadId());
hDumpFile = CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
ExpParam.ThreadId = GetCurrentThreadId();
ExpParam.ExceptionPointers = pExceptionPointers;
ExpParam.ClientPointers = TRUE;
bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL);
return EXCEPTION_EXECUTE_HANDLER;
}
void SomeFunction()
{
__try
{
int *pBadPtr = NULL;
*pBadPtr = 0;
}
__except(GenerateDump(GetExceptionInformation()))
{
}
}