How to open a webpage in ImGui - imgui

I've looked everywhere, and I can't seem to find the solution to my problem. I am wanting to know how I could use imgui to open a popup window and opening a chrome window with a website like "https://google.com". I thought that ImGui::OpenPopup might work, but then I looked at the function and then on google and it seemed like it wouldn't work. When you click a button and it redirects to a window on your computer, like when you click a link in discord and it opens a google tab on your computer.
I assumed it may look a little like this
void GUI::renderAboutMenu() noexcept
{
if (ImGui::MenuItem("My Discord"))
openWebsite("https://discord.gg/myinvitecode");
if (ImGui::MenuItem("My Patreon"))
openWebsite("https://patreon.com/myinvitecode");
}

It's not really a dear imgui question, more about how to use your OS API to perform that.
Something like that would work:
void OsOpenInShell(const char* path)
{
#ifdef _WIN32
// Note: executable path must use backslashes!
::ShellExecuteA(NULL, "open", path, NULL, NULL, SW_SHOWDEFAULT);
#else
#if __APPLE__
const char* open_executable = "open";
#else
const char* open_executable = "xdg-open";
#endif
char command[256];
snprintf(command, 256, "%s \"%s\"", open_executable, path);
system(command);
#endif
}

Related

How to add link to imGui button?

I want to create an ImGui button, when I click on this button, I want it to redirect to a url, that is, to the browser, how can I do that? can you help me please?
Creating a button:
#[imgui(
button(size = "button_size",
label = "Click me!",
catch ="click"),
separator,
display(label = "Clicks"),
)]
count: i32, }
const fn button_size() -> (f32, f32){
(100.0, 20.0)
}
However, opening a webpage is a bit harder since it depends on the api of the os that you're using. Doing that for windows and mac would look like this:
void OsOpenInShell(const char* path) {
#ifdef _WIN32
// Note: executable path must use backslashes!
::ShellExecuteA(NULL, "open", path, NULL, NULL, SW_SHOWDEFAULT);
#else
#if __APPLE__ const char* open_executable = "open";
#else
const char* open_executable = "xdg
open";
#endif char command[256];
snprintf(command, 256, "%s \"%s\"",
open_executable, path);
system(command);
#endif
Then you could put the previous code inside this:
let events = ui.imgui_ext(&mut buttons);
if events.click {
*insert code*
}

How do you create a gtk window handle from an X11 window handle

I'm trying to open a gtk file dialog window with a GLFW window.
Now since GLFW is a pretty low level API it only exposes the X11 window and display, because it just creates a window without any GUI stuff.
The problem I'm having is that gtk_file_chooser_dialog_new() expects a parent window to be passed on, but since I only have an X11 handle I'm not quite sure how to create a GTK handle from it.
I followed this tutorial which resulted in the following code:
glfwSetKeyCallback(windowHandle1, [](GLFWwindow *window, int keyCode, int scanCode, int action, int mods) {
if (action == GLFW_PRESS)
{
if (keyCode == GLFW_KEY_O && mods == (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL))
{
GtkWidget *dialog;
GtkFileChooserAction fileAction = GTK_FILE_CHOOSER_ACTION_OPEN;
gint res;
// Window x11Window = glfwGetX11Window(window);
// Display *x11Display = glfwGetX11Display();
int argc = 0;
gtk_init(&argc, nullptr); // TODO: don't do this every time
dialog = gtk_file_chooser_dialog_new("Open File",
nullptr, // should be _GtkWindow of the GLFWwindow
fileAction,
_("_Cancel"),
GTK_RESPONSE_CANCEL,
_("_Open"),
GTK_RESPONSE_ACCEPT,
nullptr);
res = gtk_dialog_run(GTK_DIALOG(dialog));
if (res == GTK_RESPONSE_ACCEPT)
{
char *filename;
GtkFileChooser *chooser = GTK_FILE_CHOOSER(dialog);
filename = gtk_file_chooser_get_filename(chooser);
std::cout << filename << std::endl;
g_free(filename);
}
gtk_widget_destroy(dialog);
std::cout << "destroyed file dialog" << std::endl;
}
}
});
This opens an open file dialog, but because I didn't specify a parent window the main window can still be focused, and another problem is that the dialog doesn't close for some reason even though I call gtk_widget_destroy(dialog).
I already took a look at this post, but the only answer seems to be getting the xid of the file dialog window, which is not what I want to do.
This google search result doesn't seem to help either, as it creates a completely new gdk (not gtk) window on the default display.
I've got the same problem and found hackish way to fix this. Null parent is not really problem here, but lack of event dispatching, so I've added:
gtk_widget_destroy(dialog);
while (g_main_context_iteration(nullptr, false));

Qt Assistant: How to maximize help window, when QT-Assistent is started as process

QT4.8
Hi,
I am connecting to QT-Assistent using a QProcess schema.
For example (from the QT doc)
QProcess *process = new QProcess;
QStringList args;
args << QLatin1String("-collectionFile")
<< QLatin1String("mycollection.qhc")
<< QLatin1String("-enableRemoteControl");
process->start(QLatin1String("assistant"), args);
if (!process->waitForStarted())
return;
and I am passing commands to it by using the suggested documentation:
QByteArray ba;
ba.append("setSource qthelp://com.mycompany.1_0_0/doc/index.html\n");
process->write(ba);
My Problem:
How to maximize the help window, in case user minimizes it?
Since the help is running as different process, did not find a way to bring the window up.
TIA.
If you launch another process, you are then required to use OS specific management tools of the windows.
You can often get the window id when the process is created, but managing its window is platform specific.
Qt hasn't left its application scope to do full shell access across platforms, but here is how you would do it in Windows:
http://qt-project.org/doc/qt-5/qprocess.html#processId
http://forums.codeguru.com/showthread.php?353149-How-to-Get-windows-Handle-using-Process-Id
https://stackoverflow.com/a/10258861/999943
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
#include <windows.h>
//...
HWND h = ::GetTopWindow(0 );
{
DWORD pid;
DWORD dwTheardId = ::GetWindowThreadProcessId( h,&pid);
if ( pid == process->processId() )
{
// here h is the handle to the window
break;
}
h = ::GetNextWindow( h , GW_HWNDNEXT);
}
::SetForegroundWindow(h);
::ShowWindow(h, SW_SHOWMAXIMIZED);
Hope that helps.

C++ _tmain would not start running

I have an mfc project which is process spawned by a windows service. For some reason the process dies before it starts. Global values get created but the process would not start the _tmain. This issue raised while moving from VC6 to VS2012.
Here is a code sample, I can place a break point and stop at this line CWinApp theApp; but I can't stop at the first line of _tmain. The program just can't find the entry point and exists.
// prog.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// The one and only application object
CWinApp theApp;
using namespace std;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
try {
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
nRetCode = 1;
}
else
{
//Some propietry code which runs here
}
return nRetCode;
}
catch(...) {
return 147;
}
}
initially I thought this issue is caused due to the MFC which accompanies VS2012. I noticed however that our development version just before the move has the same affect. This seems strange enough because the previous version has the same code and it finds the entry point just fine.
I was able to start the program by doing the following:
// prog.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// The one and only application object
using namespace std;
class MyApp : public CWinApp {
public:
MyApp() : CWinApp(_T("VCP")){}
int init(LPTSTR CommandLine);
virtual int Run()
{
return init(m_lpCmdLine);
}
};
MyApp theApp;
//int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
int MyApp::init(LPTSTR CommandLine)
{
int argc = 2;
TCHAR* argv[] = {_T(""),_T("")};
argv[1]= CommandLine;
try {
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
int nRetCode = 0;
// initialize MFC and print and error on failure
int r=1;
if (r>1)//(!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
nRetCode = 1;
}
else
{
// some propietry code
}
return nRetCode;
}
catch(...) {
return 147;
}
}
To summarize I have 3 versions of code. a release version of code which works just fine. Two development version on different Visual studios which have the same affect of not finding the entry point. a fresh mfc project contains code similar to the faulty code and it finds the _tmain.
My questions are :
Why is this happening?
How can I run with _tmain?
Your original code can only work if the EXE is linked as a console mode app. Pretty unusual for MFC apps, but it is supported. Getting MFC initialized with a call AfxWinInit() is indeed required.
But clearly your EXE isn't being linked as a console mode app or your 2nd snippet would not work. Which relies on the WinMain() implementation embedded inside MFC. The normal way that MFC apps are done.
Linker + System, SubSystem setting. It needs to be set to "Console" if a console mode app is indeed intended and you want your own main() function to be the entrypoint.

QT Translucent window and remote desktop

I'm creating a Qt/C++ application using QML for some parts. Under windows I would like to make use of the translucent windowing using ExtendFrameIntoClientArea as seen in this snippet from my window class.
#ifdef Q_WS_WIN
if ( QSysInfo::windowsVersion() == QSysInfo::WV_VISTA ||
QSysInfo::windowsVersion() == QSysInfo::WV_WINDOWS7 )
{
EnableBlurBehindWidget(this, true);
ExtendFrameIntoClientArea(this);
}
#else
The code is working nicely with one exception. If the transparent window system is turned off the background becomes black, and as part of my UI is transparent it becomes dark as well. The same thing happens when logging in to a remote computer running the application, even if the transparent windowing system is re-initialized immediately the background stays black until the above code is executed again. This is demonstrated in this image: Comparison of failed rendering (in background) and correct (in front).
The problem is to find a signal to connect to re-initializing the transparent window, or better yet to detect when windows are drawn transparently and draw the UI accordingly. Any alternative solutions are also welcome.
After digging around in both Qt and MSDN Aero documentation I came up with a two step solution. By overriding the winEvent method of my main window, I was able to receive the signal which is triggered every time the translucent window system is enabled or disabled.
#define WM_DWMCOMPOSITIONCHANGED 0x031E
bool MainWindow::winEvent(MSG *message, long *result) {
if ( message->message == WM_DWMCOMPOSITIONCHANGED ) {
// window manager signaled change in composition
return true;
}
return false;
}
That took me quite close, but it didn't tell me whether DWM was currently drawing transparent windows or not. By using dwmapi.dll I was able to find a method which does exactly that, and it can be accessed like below:
// QtDwmApi.cpp
extern "C"
{
typedef HRESULT (WINAPI *t_DwmIsCompositionEnabled)(BOOL *pfEnabled);
}
bool DwmIsCompositionEnabled() {
HMODULE shell;
shell = LoadLibrary(L"dwmapi.dll");
if (shell) {
BOOL enabled;
t_DwmIsCompositionEnabled is_composition_enabled = \
reinterpret_cast<t_DwmIsCompositionEnabled>(
GetProcAddress (shell, "DwmIsCompositionEnabled")
);
is_composition_enabled(&enabled);
FreeLibrary (shell);
if ( enabled ) {
return true;
} else {
return false;
}
}
return false;
}
My implementation is now able to react to changes in Aero and draw the GUI accordingly. When logging in over remote desktop the window is drawn using transparency as well where available.
The function should be written as follows to avoid the GPA failure
// QtDwmApi.cpp
extern "C"
{
typedef HRESULT (WINAPI *t_DwmIsCompositionEnabled)(BOOL *pfEnabled);
}
bool DwmIsCompositionEnabled() {
HMODULE shell;
BOOL enabled=false;
shell = LoadLibrary(L"dwmapi.dll");
if (shell) {
t_DwmIsCompositionEnabled is_composition_enabled = \
reinterpret_cast<t_DwmIsCompositionEnabled>(
GetProcAddress (shell, "DwmIsCompositionEnabled")
);
if (is_composition_enabled)
is_composition_enabled(&enabled);
FreeLibrary (shell);
}
return enabled;
}