The following code returns 0 to wnd but right after the CreateDialog the error is ERROR_SUCCESS. The dialog doesn't show up and I don't understand how this is possible. It's a console project and the dialog is created in vs2013, if that's relevant.
#include <windows.h>
#include "resource.h"
int main(){
HWND wnd = CreateDialog(NULL, MAKEINTRESOURCE(IDD_DIALOG1), NULL, NULL);
ShowWindow(wnd, SW_SHOWDEFAULT);
UpdateWindow(wnd);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
This has to be some really stupid mistake but I can't see it.
You'll need to initialise the rich edit library first - if the library isn't loaded, the control won't be registered and the dialog creation will fail.
See the note at http://msdn.microsoft.com/en-us/library/windows/desktop/hh298375(v=vs.85).aspx about calling LoadLibrary. You need to do this before creating the dialog.
Alternatively setting the DS_NOFAILCREATE style should allow the dialog to be created although the rich edit control won't show up.
Had same exact problem my Dialog wouldn't appear it was in-fact missing the RichText2.0 Control load up.
This is how I fixed it should support any windows version.
Add this include to your project
#include <richedit.h> // To use richedit control
//Load RichText4.1 or 2.0/3.0 or 1.0 (last resort) Control first. (3 different DLL's for full support).
//
// FUNCTION: IsWinXPSp1Min()
//
// PURPOSE: Return TRUE if operating sytem is Windows XP SP1 or later.
// Windows XP SP1 is the minimum system required to use a richedit v4.1 but only
// when UNICODE is defined.
//
BOOL IsWinXPSp1Min()
{
OSVERSIONINFO osvi = { sizeof(osvi) };
if (!GetVersionEx(&osvi))
{
return FALSE;
}
// Determine if system is Windows XP minimum
if (osvi.dwMajorVersion >= 5 && osvi.dwMinorVersion >= 1)
{
// Now check if system is specifically WinXP and, if so, what service pack
// version is installed.
if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
{
// The following test assumes that the szCSDVersion member of the
// OSVERSIONINFO struct's format will always be a string like
// "Service Pack x", where 'x' is a number >= 1. This is fine for SP1
// and SP2 but future service packs may have a different string
// descriptor.
TCHAR* pszCSDVersion = L"Service Pack 1";
if (osvi.szCSDVersion < pszCSDVersion)
{
return FALSE;
}
}
return TRUE;
}
return FALSE;
}
//
// FUNCTION: GetRichEditClassName()
//
// PURPOSE: Load the proper version of RichEdit and return the class name.
//
PCWSTR GetRichEditClassName()
{
HINSTANCE hLib;
// Try to load latest version of rich edit control. Since v4.1 is available
// only as an UNICODE control on a minimum of Windows XP with service pack 1
// installed, use preprocessor conditional to ensure that an attempt to load
// Msftedit.dll is only made if UNICODE is defined.
#if defined UNICODE
if (IsWinXPSp1Min())
{
// Try to get richedit v4.1, explicitly use wide character string as this
// is UNICODE only.
hLib = LoadLibrary(L"msftedit.dll");
if (hLib)
{
return MSFTEDIT_CLASS;
}
}
#endif
// Cannot get latest version (v4.1) so try to get earlier one
// Rich Edit Version 2.0/3.0
hLib = LoadLibrary(L"riched20.dll");
if (hLib)
{
// Version 2.0/3.0 is good
return RICHEDIT_CLASS;
}
// Rich Edit Version 1.0
hLib = LoadLibrary(L"riched32.dll");
if (hLib)
{
// Version 1.0 is good
return L"RichEdit";
}
// Cannot get any versions of RichEdit control (error)
return L"";
}
resource.h file
#define IDC_RICHEDIT 3990
Create the actual RichEdit control
// // FUNCTION: OnInitRichEditDialog(HWND, HWND, LPARAM) // // PURPOSE: Process the WM_INITDIALOG message // BOOL OnInitRichEditDialog(HWND hWnd, HWND hWndFocus, LPARAM lParam) {
RECT rc = { 20, 20, 160, 250 };
HWND hRichEdit = CreateWindowEx(WS_EX_CLIENTEDGE, GetRichEditClassName(),
L"RichEdit Control",
ES_MULTILINE | ES_AUTOHSCROLL | WS_HSCROLL | ES_AUTOVSCROLL |
WS_VSCROLL | WS_CHILD | WS_VISIBLE,
rc.left, rc.top, rc.right, rc.bottom,
hWnd, reinterpret_cast<HMENU>(IDC_RICHEDIT), g_hInst, 0);
if (hRichEdit)
{
SendMessage(hRichEdit, WM_SETFONT, reinterpret_cast<WPARAM>(g_hFont), TRUE);
}
return TRUE; }
Related
I am looking for the normal way (that is, the way Microsoft thought about when creating its API) to load standard icons for commands in a pure C program, like the floppy disc image for saving, etc.
The Internet doesn't seem to contain the answer. I know the toolbars of commctl32 can receive a TB_LOADIMAGES message that fills an image list with standard icons, but what if I don't need toolbars in my app? I want icons in another control, let's say on an owner-draw button, or a menu item. Is there a way to fill the image list without creating a useless toolbar? Or even better, getting HICON or HBITMAP handles to avoid the commctl32 dependency?
The loud silence about it in Microsoft's docs, and on the web, makes me think there is no such feature. Maybe when an application is developed with Microsoft tools, the application creator injects as resources in the executable files the default icons the developer chooses in a predefined list? I cannot check it because I only use Unix-like compilers, can somebody confirm that and/or tell me more about default icon usage under Windows?
Also, would it be reliable to assume we can load libraries like shell32.dll to use its embedded icons (like all the good old functions that are available since an eternity in kernel32.dll, `user32.dll, ...)? I mean, is there a guarantee that icons in libraries will keep their semantics and indexes in future versions of Windows?
Coming some days later to post the final solution I opted for, just in case somebody would need to use the same. The most normal way to show command icons is to embed them in the application, so despite being unhappy with the creation of a dummy control, I use a temporary toolbar to load the icons in global image lists. This would unlikely fail, but since icons may sometimes be the only thing that indicates to the user what a widget does, I reinforced the conditions with the ability to run a fallback code when something is wrong.
The function that loads the icons is named WIN32_initIcons(), because it is supposed to be implemented alongside with something like a GTK_initIcons() or X11_initIcons() counterpart for Unix-like platforms.
HIMAGELIST WIN32_imglst16 = NULL;
HIMAGELIST WIN32_imglst24 = NULL;
bool WIN32_initIcons(void) {
bool def16 = false;
bool def32 = false;
HWND hWnd;
WIN32_imglst16 = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 80, 16);
WIN32_imglst32 = ImageList_Create(24, 24, ILC_COLOR32 | ILC_MASK, 80, 16);
if (hWnd = CreateWindowA("ToolbarWindow32", NULL, TBSTYLE_LIST, 0, 0, 0, 0, NULL, (HMENU)0, GetModuleHandle(NULL), NULL)) {
if (WIN32_imglst16) {
SendMessage(hWnd, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)WIN32_imglst16);
if (!SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_STD_SMALL_COLOR, (LPARAM)HINST_COMMCTRL)) def16 = true;
if (SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_VIEW_SMALL_COLOR, (LPARAM)HINST_COMMCTRL) != 15) def16 = false;
if (SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_HIST_SMALL_COLOR, (LPARAM)HINST_COMMCTRL) != 27) def16 = false;
if (ImageList_GetImageCount(WIN32_imglst16) != 32) def16 = false;
}
if (WIN32_imglst24) {
SendMessage(hWnd, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)WIN32_imglst24);
if (!SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_STD_SMALL_COLOR, (LPARAM)HINST_COMMCTRL)) def24 = true;
if (SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_VIEW_SMALL_COLOR, (LPARAM)HINST_COMMCTRL) != 15) def24 = false;
if (SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_HIST_SMALL_COLOR, (LPARAM)HINST_COMMCTRL) != 27) def24 = false;
if (ImageList_GetImageCount(WIN32_imglst24) != 32) def24 = false;
}
DestroyWindow(hWnd);
}
if (WIN32_imglst16 && !def16) {
// Load your custom 16x16 fallback icons in the list "WIN32_imglst16" here
// Don't forget to set "def16 = true" on success
}
if (WIN32_imglst24 && !def24) {
// Load your custom 24x24 fallback icons in the list "WIN32_imglst24" here
// Don't forget to set "def24 = true" on success
}
if (!def16) {
// Trigger your error management here because 16x16 icons cannot be loaded
// Maybe, call "ImageList_Destroy(WIN32_imglst16)" and set "WIN32_imglst16 = NULL"
}
if (!def24) {
// Trigger your error management here because 24x24 icons cannot be loaded
// Maybe, call "ImageList_Destroy(WIN32_imglst24)" and set "WIN32_imglst24 = NULL"
}
return (def16 && def24);
}
Note: In simple C, use <stdbool.h> to define the bool value.
I created an application by slightly modifying the Magnification API sample provided by Microsoft to implement a custom transformation of each frame captured and displayed in the Magnifier window.
I used the MagSetImageScalingCallback to set the my function as a callback. The callback is invoked without problem and the source and destination image can be easily manipulated because the raw bits are passed to the callback as pointers (srcdata and destdata).
The window is refreshed with a timer which is set to 16 ms (~60Hz). The refresh is invoked by using the InvalidateRect API. The problem is that when the magnifier window suffer from flickering. This happens especially when the start menu appears, if "Peek" is enabled or every time there is a window on foreground which has dynamic content.
I tried to intercept the WM_ERASEBKGND and invoke the InvalidateRect with FALSE as third parameter but this didn't help. I tried to add an UpdateWindow invocation before the invalidate but nothing changed.
The Magnifier application provided with Windows 10 doesn't have the same problem. I'm wondering why this is happening and how can I get rid of flickering.
In order to reproduce che problem download the Magnification API sample from the link above then replace the content in the file MagnifierSample.cpp with this source code:
// Ensure that the following definition is in effect before winuser.h is included.
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include <windows.h>
#include <wincodec.h>
#include <magnification.h>
// For simplicity, the sample uses a constant magnification factor.
#define RESTOREDWINDOWSTYLES WS_POPUP
// Global variables and strings.
HINSTANCE hInst;
const TCHAR WindowClassName[]= TEXT("MagnifierWindow");
const TCHAR WindowTitle[]= TEXT("Screen Magnifier Sample");
const UINT timerInterval = 16; // close to the refresh rate #60hz
HWND hwndMag;
HWND hwndHost;
RECT magWindowRect;
RECT hostWindowRect;
// Forward declarations.
ATOM RegisterHostWindowClass(HINSTANCE hInstance);
BOOL SetupMagnifier(HINSTANCE hinst);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void CALLBACK UpdateMagWindow(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
BOOL isFullScreen = FALSE;
//
// FUNCTION: WinMain()
//
// PURPOSE: Entry point for the application.
//
int APIENTRY WinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE /*hPrevInstance*/,
_In_ LPSTR /*lpCmdLine*/,
_In_ int nCmdShow)
{
if (FALSE == MagInitialize())
{
return 0;
}
if (FALSE == SetupMagnifier(hInstance))
{
return 0;
}
ShowWindow(hwndHost, nCmdShow);
UpdateWindow(hwndHost);
// Create a timer to update the control.
UINT_PTR timerId = SetTimer(hwndHost, 0, timerInterval, UpdateMagWindow);
// Main message loop.
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Shut down.
KillTimer(NULL, timerId);
MagUninitialize();
return (int) msg.wParam;
}
//
// FUNCTION: HostWndProc()
//
// PURPOSE: Window procedure for the window that hosts the magnifier control.
//
LRESULT CALLBACK HostWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_ERASEBKGND:
return TRUE;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
//
// FUNCTION: RegisterHostWindowClass()
//
// PURPOSE: Registers the window class for the window that contains the magnification control.
//
ATOM RegisterHostWindowClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex = {};
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = HostWndProc;
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
wcex.lpszClassName = WindowClassName;
return RegisterClassEx(&wcex);
}
static BOOL CALLBACK myCallBack(HWND hwnd, void *srcdata, MAGIMAGEHEADER srcheader, void *destdata, MAGIMAGEHEADER destheader, RECT unclipped, RECT clipped, HRGN dirty) {
UINT row;
UINT column;
BYTE *matrix;
memset(destdata, 0, destheader.cbSize);
matrix = (BYTE *) destdata;
//Set alpha bits for the resulting image to 255 (fully opaque)
for (row = 0; row < destheader.height; row++) {
for (column = 3; column < destheader.width; column += 4) {
matrix[(row * destheader.width) + column] = 0xFF;
}
}
Sleep(20);
return TRUE;
}
//
// FUNCTION: SetupMagnifier
//
// PURPOSE: Creates the windows and initializes magnification.
//
BOOL SetupMagnifier(HINSTANCE hinst)
{
// Set bounds of host window according to screen size.
hostWindowRect.top = 0;
hostWindowRect.bottom = GetSystemMetrics(SM_CYSCREEN);
hostWindowRect.left = 0;
hostWindowRect.right = GetSystemMetrics(SM_CXSCREEN);
// Create the host window.
RegisterHostWindowClass(hinst);
hwndHost = CreateWindowEx(WS_EX_TOPMOST | WS_EX_LAYERED, WindowClassName, WindowTitle, RESTOREDWINDOWSTYLES, 0, 0, hostWindowRect.right, hostWindowRect.bottom, NULL, NULL, hInst, NULL);
if (!hwndHost)
{
return FALSE;
}
// Make the window opaque.
SetLayeredWindowAttributes(hwndHost, 0, 255, LWA_ALPHA);
SetWindowLong(hwndHost, GWL_EXSTYLE, GetWindowLong(hwndHost, GWL_EXSTYLE) | WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST | WS_EX_NOACTIVATE);
// Create a magnifier control that fills the client area.
magWindowRect = hostWindowRect;
hwndMag = CreateWindow(WC_MAGNIFIER, TEXT("MagnifierWindow"), WS_CHILD | WS_VISIBLE, magWindowRect.left, magWindowRect.top, magWindowRect.right, magWindowRect.bottom, hwndHost, NULL, hInst, NULL );
if (!hwndMag)
{
return FALSE;
}
MagSetImageScalingCallback(hwndMag, &myCallBack);
// Set the source rectangle for the magnifier control.
MagSetWindowSource(hwndMag, magWindowRect);
return 1;
}
//
// FUNCTION: UpdateMagWindow()
//
// PURPOSE: Sets the source rectangle and updates the window. Called by a timer.
//
void CALLBACK UpdateMagWindow(HWND /*hwnd*/, UINT /*uMsg*/, UINT_PTR /*idEvent*/, DWORD /*dwTime*/)
{
// Reclaim topmost status, to prevent unmagnified menus from remaining in view.
SetWindowPos(hwndHost, HWND_TOPMOST, 0, 0, magWindowRect.right, magWindowRect.bottom, SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
// Force redraw.
InvalidateRect(hwndMag, NULL, FALSE);
}
Notice that I added the code to set the callback
BOOL ret = MagSetImageScalingCallback(hwndMag, &myCallBack);
then I created this callback:
static BOOL CALLBACK myCallBack(HWND hwnd, void *srcdata, MAGIMAGEHEADER srcheader, void *destdata, MAGIMAGEHEADER destheader, RECT unclipped, RECT clipped, HRGN dirty)
The Sleep statement "simulate" the time taken by my custom transformation.
If you open a youtube video with Edge and then you run the MagnifierSample.exe executable you should see a black screen flickering sometime and when the screen flickers you should see the content behind the magnifier window (the black screen). This is exactly what is happening in my application. The sleep value is set to 20 but I don't known how long the callback is actually taking. I just guessed that it might take more than 16 ms.
To reproduce the problem perform the following steps:
Run the MagnifierSample.exe manually (don't use the debugger to run it)
You should see a black screen
Press the window key
Set a window with a video or a dynamic content in foreground
Click on the black window to let the taskbar disappear
You should see the screen flashing sometime
Is it possible to set a callback similar to the MagSetImageScalingCallback for a normal window handle ? I know I can use the WindowProc callback to intercept the messages sent to the window however I don't have access to the rawbits unless I use CreateDIBSection, SelectObject etc ...but at that time the image has been already sent to the destination window and I don't have the chance to transform it.
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.
First of all, let me get my point for this:
This is an emergency alert system, it pulls from a website which we manipulate in the back office, the program can be minimized but cannot be closed (easily, at least none of the people that will use it will know how). As you can see, if the program was closed the Emergency Alerts wouldn't be seen/heard....that's an issue. I have to deploy this application on over 200 computers so I want it simple, I don't want to create a scheduled task, etc.. to keep it running. I simply want it to not be easy to close.
See my code, below:
/* example.c
This is a Win32 C application (ie, no MFC, WTL, nor even any C++ -- just plain C) that demonstrates
how to embed a browser "control" (actually, an OLE object) in your own window (in order to display a
web page, or an HTML file on disk). The bulk of the OLE/COM code is in DLL.c which creates a DLL that
we use in this simple app. Furthermore, we use LoadLibrary and GetProcAddress, so our DLL is not
actually loaded until/unless we need it.
NOTE: The DLL we create does not normally use UNICODE strings. If you compile this example as UNICODE,
then you should do the same with DLL.C.
*/
#include <windows.h>
#include "..\CWebPage.h" /* Declarations of the functions in DLL.c */
// A running count of how many windows we have open that contain a browser object
unsigned char WindowCount = 0;
// The class name of our Window to host the browser. It can be anything of your choosing.
static const TCHAR ClassName[] = "EAS";
// Where we store the pointers to CWebPage.dll's functions
EmbedBrowserObjectPtr *lpEmbedBrowserObject;
UnEmbedBrowserObjectPtr *lpUnEmbedBrowserObject;
DisplayHTMLPagePtr *lpDisplayHTMLPage;
DisplayHTMLStrPtr *lpDisplayHTMLStr;
/****************************** WindowProc() ***************************
* Our message handler for our window to host the browser.
*/
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_CREATE)
{
// Embed the browser object into our host window. We need do this only
// once. Note that the browser object will start calling some of our
// IOleInPlaceFrame and IOleClientSite functions as soon as we start
// calling browser object functions in EmbedBrowserObject().
if ((*lpEmbedBrowserObject)(hwnd)) return(-1);
// Another window created with an embedded browser object
++WindowCount;
// Success
return(0);
}
if (uMsg == WM_DESTROY)
{
// Detach the browser object from this window, and free resources.
(*lpUnEmbedBrowserObject)(hwnd);
// One less window
--WindowCount;
// If all the windows are now closed, quit this app
if (!WindowCount) PostQuitMessage(0);
return(TRUE);
}
// NOTE: If you want to resize the area that the browser object occupies when you
// resize the window, then handle WM_SIZE and use the IWebBrowser2's put_Width()
// and put_Height() to give it the new dimensions.
return(DefWindowProc(hwnd, uMsg, wParam, lParam));
}
/****************************** WinMain() ***************************
* C program entry point.
*
* This creates a window to host the web browser, and displays a web
* page.
*/
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hInstNULL, LPSTR lpszCmdLine, int nCmdShow)
{
HINSTANCE cwebdll;
MSG msg;
WNDCLASSEX wc;
// Load our DLL containing the OLE/COM code. We do this once-only. It's named "cwebpage.dll"
if ((cwebdll = LoadLibrary("cwebpage.dll")))
{
// Get pointers to the EmbedBrowserObject, DisplayHTMLPage, DisplayHTMLStr, and UnEmbedBrowserObject
// functions, and store them in some globals.
// Get the address of the EmbedBrowserObject() function. NOTE: Only Reginald has this one
lpEmbedBrowserObject = (EmbedBrowserObjectPtr *)GetProcAddress((HINSTANCE)cwebdll, "EmbedBrowserObject");
// Get the address of the UnEmbedBrowserObject() function. NOTE: Only Reginald has this one
lpUnEmbedBrowserObject = (UnEmbedBrowserObjectPtr *)GetProcAddress((HINSTANCE)cwebdll, "UnEmbedBrowserObject");
// Get the address of the DisplayHTMLPagePtr() function
lpDisplayHTMLPage = (DisplayHTMLPagePtr *)GetProcAddress((HINSTANCE)cwebdll, "DisplayHTMLPage");
// Get the address of the DisplayHTMLStr() function
lpDisplayHTMLStr = (DisplayHTMLStrPtr *)GetProcAddress((HINSTANCE)cwebdll, "DisplayHTMLStr");
// Register the class of our window to host the browser. 'WindowProc' is our message handler
// and 'ClassName' is the class name. You can choose any class name you want.
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.hInstance = hInstance;
wc.lpfnWndProc = WindowProc;
wc.lpszClassName = &ClassName[0];
RegisterClassEx(&wc);
// Create another window with another browser object embedded in it.
if ((msg.hwnd = CreateWindowEx(0, &ClassName[0], "Emergency Alert System", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
HWND_DESKTOP, NULL, hInstance, 0)))
{
// For this window, display a URL. This could also be a HTML file on disk such as "c:\\myfile.htm".
(*lpDisplayHTMLPage)(msg.hwnd, "http://www.google.com");
// Show the window.
ShowWindow(msg.hwnd, nCmdShow);
UpdateWindow(msg.hwnd);
}
// Do a message loop until WM_QUIT.
while (GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Free the DLL.
FreeLibrary(cwebdll);
return(0);
}
MessageBox(0, "Can't open cwebpage.dll! You are not protected by Emergency Alerting System. Click OK to terminate this application. Contact the developer, Scott Plunkett.", "ERROR", MB_OK);
return(-1);
}
It took this from an example tutorial I found, I have never done any windows programming before so I had to figure out a quick solution.
I appreciate any and all help on this.
If you create a handler for the WM_SYSCOMMAND message and check for the SC_SYSCLOSE parameter, you can stop it from executing the default action of closing the window.
I noticed it's not an MFC application, so you have to call Win32 Library to enable the feature.
Try this out:http://www.davekb.com/browse_programming_tips:win32_disable_close_button:txt
---EDIT---
Sorry the code did not work out. I did not have resources to debug it.
To disable the X of the window, you can either set CS_NOCLOSE property of WNDCLASSEX:
wc.style = CS_NOCLOSE;//in your code
or rewrite the WM_CLOSE message handler function. Thanks.
I want to display an image in OpenCV in a full screen borderless window.
In other words, only the image pixels will appear, without menu, toolbar, or window background.
Using imshow() or cvShowImage() don't enable it:
The window grows to be full screen
in width but not in height. It misses few pixels.
I could not make it borderless even by changing settings of window
handler.
I think that the problem is rooted in cvNamedWindow() method which creates main WS_OVERLAPPED window, then creates a child and all functions like imshow() or cvGetWindowHandle() operate on the child.
Thus even windows command:
SetWindowLong((HWND)cvGetWindowHandle(winName), GWL_STYLE, WS_VISIBLE | WS_EX_TOPMOST | WS_POPUP);
Doesnt help, since the child cannot become borderless WS_POPUP. Someone got a workaround?
Maybe, showing opencv mat to window
without using opencv built in methods
Or some kind of windows trick
P.S. I tried the following code:
cvMoveWindow("AAA",0,0);
cvSetWindowProperty("AAA", CV_WINDOW_FULLSCREEN, CV_WINDOW_FULLSCREEN);
// Also I tried this:
HWND hwnd = (HWND)cvGetWindowHandle("AAA");
RECT windowRect;
windowRect.left = 0;
windowRect.top = 0;
windowRect.right = cxScreen; //Display resolution
windowRect.bottom = cyScreen; //Display resolution
AdjustWindowRect(&windowRect,WS_VISIBLE,false);
long p_OldWindowStyle = SetWindowLongPtr(hwnd,GWL_STYLE,WS_POPUP);
SetWindowPos(hwnd,HWND_TOP,0,0,windowRect.right,windowRect.bottom,SWP_FRAMECHANGED | SWP_SHOWWINDOW);
SetWindowLong(hwnd, GWL_STYLE, WS_VISIBLE | WS_EX_TOPMOST | WS_POPUP);
Have you issued cvShowImage() to display the window? Because it seems you are not doing it. Anyway, you might want to call the win32 API for this instead, so add a call to ShowWindow(hwnd, SW_SHOW); after SetWindowPos().
If your current call to SetWindowPos() doesn't do the trick, check this answer: Hide border of window, if i know a handle of this window
I recommend you doing your tests without calling cvSetWindowProperty() at first, just to make sure you can find a method that works.
Just a note, if you check modules/highgui/src/window_w32.cpp you can see how OpenCV creates windows on Windows.
EDIT:
The following code implements the tips I gave before and bypasses the problems the OP reported. The trick is NOT using cvGetWindowHandle() to retrieve the windows' handle and use directly win32 API for that: FindWindow()
IplImage* cv_img = cvLoadImage("test.jpg", CV_LOAD_IMAGE_UNCHANGED);
if(!cv_img)
{
printf("Failed cvLoadImage\n");
return -1;
}
cvNamedWindow("main_win", CV_WINDOW_AUTOSIZE);
cvMoveWindow("main_win", 0, 0);
cvSetWindowProperty("main_win", CV_WINDOW_FULLSCREEN, CV_WINDOW_FULLSCREEN);
cvShowImage("main_win", cv_img);
//HWND cv_hwnd = (HWND)cvGetWindowHandle("main_win");
//if (!cv_hwnd)
//{
// printf("Failed cvGetWindowHandle\n");
//}
//printf("cvGetWindowHandle returned %p\n", *cv_hwnd);
HWND win_handle = FindWindow(0, L"main_win");
if (!win_handle)
{
printf("Failed FindWindow\n");
}
SetWindowLong(win_handle, GWL_STYLE, GetWindowLong(win_handle, GWL_EXSTYLE) | WS_EX_TOPMOST);
ShowWindow(win_handle, SW_SHOW);
cvWaitKey(0);
cvReleaseImage(&cv_img);
cvDestroyWindow("main_win");
This code will make the window created by OpenCV borderless, but you still might have to tweak one thing or another to make this operation perfect. You'll see why. One idea is to resize the window and make it the size of the image.
EDIT:
Well, since you stated:
writing a demo might be very hard
I also decided to do this last part for you, since I'm such a nice guy =]
This is a small improvement of the code above:
HWND win_handle = FindWindow(0, L"main_win");
if (!win_handle)
{
printf("Failed FindWindow\n");
}
// Resize
unsigned int flags = (SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER);
flags &= ~SWP_NOSIZE;
unsigned int x = 0;
unsigned int y = 0;
unsigned int w = cv_img->width;
unsigned int h = cv_img->height;
SetWindowPos(win_handle, HWND_NOTOPMOST, x, y, w, h, flags);
// Borderless
SetWindowLong(win_handle, GWL_STYLE, GetWindowLong(win_handle, GWL_EXSTYLE) | WS_EX_TOPMOST);
ShowWindow(win_handle, SW_SHOW);
And on my system it displays exactly what you asked on the question.