I am using WIN32 and C programming to do a window dialog in Visual Studio 2008 in the Windows CE OS using Windows 5.0 Mobile SDK. I insert my two picture boxes using the Resource Dialog Editor and ensure they are allocated IDs in the window resource. I am using SHLoadDIBitmap to display the image. My code compiles without errors but when I run the program, no images appear in the two picture boxes. What am I doing wrong?
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <windowsx.h>
#include <winuser.h>
#include "ScanCAPI.h"
#include "resource.h"
#pragma comment(lib, "Kernel32.lib")
HBITMAP hImage;
HBITMAP hImage1;
.
.
.
switch(uMsg)
{
case WM_INITDIALOG:
hImage = SHLoadDIBitmap(TEXT("\\My Documents\\image1.bmp"));
hImage1 = SHLoadDIBitmap(TEXT("\\My Documents\\image2.bmp"));
if (hImage==NULL) {
MessageBox(0,"hImage returned null",0,0);
} else {
hnd_pic1 = GetDlgItem(hwnd,IDC_STATIC8);
SendMessage(hnd_pic1, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImage);
}
hnd_pic2 = GetDlgItem(hwnd,IDC_STATIC9);
if (hImage1==NULL) {
MessageBox(0,"hImage1 returned null",0,0);
} else {
SendMessage(hnd_pic2, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImage1);
}
The following code sample works for me on Windows 10 (SHLoadDIBitmap API seems not valid for Windows 10. I use LoadImage API instead.). You can refer to.
C++ code in dialog box procedure:
case WM_INITDIALOG:
hImage = LoadImage(NULL, L"full_path_to\\image3.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE);
if (NULL == hImage)
errCode = GetLastError();
hwd_static_img = GetDlgItem(hDlg, IDC_STATIC6);
SendMessage(hwd_static_img, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImage);
return (INT_PTR)TRUE;
Resource script in project_name.rc file:
CONTROL "",IDC_STATIC6,"Static", SS_BITMAP,37,133,136,109
Two notes:
Make sure the image file is a valid bitmap file. For example, you can draw a picture and save as a bitmap using mspaint.exe. If you rename a file from .PNG to .BMP, LoadImage will return a NULL handle but GetLastError return 0 which indicate no error.
Make sure set SS_BITMAP static control style for picture control (IDC_STATIC6).
BTW, no need to put image file in same directory with your project or EXE. Specify the valid full path of the image file will work.
Related
I am currently working with images in C & WinAPI, and I want to generate an HBITMAP from a given image path (of a .png picture, for example).
I have managed to write the function solution using GDI+:
#include <windows.h>
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")
HBITMAP generateBitmap(const char* filePath)
{
HBITMAP res = NULL;
std::string fileNameStr = filePath; //convert from char* to std::string
std::wstring unicodeFileName(fileNameStr.begin(), fileNameStr.end()); //convert from string to wstring
GdiPlus::Bitmap bitmap(unicodeFileName.c_str(), false); //gets bitmap from path
bitmap.GetHBITMAP(0, &res);
return res;
}
The problem with this solution, however, is that it requires the GDI+ library, which does not have (as far as I know) a C-compatible version (as it uses features such as classes and templates, it is for C++ only).
Is there any way to implement the function generateBitmap in C, without using C++?
I'm trying to learn X11. It's very hard to me, because I don't have experience with window applications on Linux.
I wrote some simple code and I can't resolve this not visible text problem.
Everything is working good probably, when I was trying to draw rectangle with DrawRectangle function it was working.
Here is the code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
int main()
{
Display* myDisplay;
Window myWindow;
int myScreen;
GC myGC;
XEvent myEvent;
unsigned long black, white;
char* hello = "Hello world!";
XFontStruct* myFont;
if((myDisplay = XOpenDisplay(NULL)) == NULL)
{
puts("Error in conneting to X Server!");
return -1;
}
myScreen = DefaultScreen(myDisplay);
black = BlackPixel(myDisplay, myScreen);
white = WhitePixel(myDisplay, myScreen);
myWindow = XCreateSimpleWindow(myDisplay, RootWindow(myDisplay, myScreen), 0, 0, 640, 320, 5, black, white);
XSelectInput(myDisplay, myWindow, ExposureMask);
XClearWindow(myDisplay, myWindow);
XMapWindow(myDisplay, myWindow);
myGC = XCreateGC(myDisplay, myWindow, 0, 0);
XSetForeground(myDisplay, myGC, black);
XSetBackground(myDisplay, myGC, white);
myFont = XLoadQueryFont(myDisplay, "-Misc-Fixed-Medium-R-Normal--7-70-75-75-C-50-ISO10646-1");
XSetFont(myDisplay, myGC, myFont->fid);
while(1)
{
XNextEvent(myDisplay, &myEvent);
if(myEvent.type == Expose)
{
XClearWindow(myDisplay, myWindow);
// HERE I DONT KNOW WHY IT DOESNT WORK!
XDrawString(myDisplay, myWindow, myGC, 0, 0, hello, strlen(hello));
}
}
XFreeGC(myDisplay, myGC);
XDestroyWindow(myDisplay, myWindow);
XCloseDisplay(myDisplay);
return 0;
}
Thank you for help!
Your font path argument to XLoadQueryFont is wrong (on my Linux/Debian desktop). Check with the xlsfonts command the right ones (they are all lowercases).
With
myFont = XLoadQueryFont
(myDisplay,
"-misc-fixed-medium-r-normal--9-90-75-75-c-60-iso10646-1");
it could work better. Try also with "lucidasanstypewriter-bold-14"
And most importantly the coordinates passed to XDrawString are wrong. Remember that they are the coordinates of the baseline of your text. And x=0, y=0 is the top left corner of the window, and y is growing downwards and x is growing to the right. Hence your text is drawn off-window, above its top. So y should be positive and more than the font height.
Try
XDrawString (myDisplay, myWindow, myGC, 15, 20, hello,
strlen (hello));
As I commented, you need to handle a lot more events.
I don't have experience with window applications on Linux.
And to learn about GUI programming, I strongly recommend first using some toolkit like GTK or Qt or perhaps SDL.
Raw X11 programming is too hard (and by the time you'll learn it is will be obsolete, e.g. by Wayland), in particular because an X11 application needs to be ICCCM & EWMH compliant. Notice that the entire X11 documentation requires nearly ten thousand pages.
See also https://tronche.com/gui/x/xlib/
BTW, most Linux GUI applications are drawing pixmap client side and sending it to the X11 server. Read about compositing window managers. Drawing requests like XDrawString are no more used anymore in practice. Recent font related libraries like libfontconfig, libXft, etc are working on the client side.
I know that I can display a .png file, So I was thought that i can display a .gif file.
I am using opencv and i will send the code for the displaying of the .png file (that is working when you change the directory to a valid one).
#include <stdio.h>
#include <opencv2\highgui\highgui_c.h>
int main(void)
{
int i;
cvNamedWindow("Display window", CV_WINDOW_AUTOSIZE); //create a window
//create an image
IplImage* image = cvLoadImage("C:\\c1.png", 1); //change to a valid directory
if (!image)//The image is empty.
{
printf("could not open image\n");
}
else
{
cvShowImage("Display window", image);
cvWaitKey(0);
system("pause");
cvReleaseImage(&image);
}
return 0;
}
unfortunately there is no direct gif support in opencv.
cv2.imread(image.gif) is not possible.But there are many other alternatives to insert a GIF
You can use moviepy module to make it happen
Link for moviepy
Here is an example:
Converting a video excerpt into a GIF
importing moviepy module
from moviepy.editor import *
Then a video file is opened and selected the part between 1’22.65 (1
minute 22.65 seconds) and 1’23.2, reduce its size (to 30% of the
original) and save it as a GIF
clip = (VideoFileClip("frozen_trailer.mp4").subclip((1,22.65),(1,23.2)).resize(0.3))
clip.write_gif("use_your_head.gif")
I recently started using Dev C++ 4.9.9.2 to experiment with graphics program in C(thanks to this tutorial). But for some reason setbkcolor() does absolutely nothing. Here's the code...
#include <stdio.h>
#include <graphics.h>
#include <conio.h>
int main()
{
initwindow(800,600);
setbkcolor(GREEN); //FAILED. also tried "setbkcolor(2);"
while ( !kbhit() ){}
return 0;
}
Here's the Output:
I am using Windows 7 Professional. Is this something to do with the Operating System?
The documentation says in the Windows notes part:
Also, only future drawing will use the new background color (anything currently drawn in the old background color will stay in the old color). Calling setbkcolor(0) will change the background color to the current color at index [0] of the palette (rather than always changing the background to black).
You have misunderstood the goal of the function.
since the window is drawn before even setting the background color.
use cleardevice() after setting the background color to recreate the screen.
#include<stdio.h>
#include<graphics.h>
int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "");
setbkcolor(GREEN);
cleardevice();
getch();
closegraph();
return 0;
}
I have the follow starting code to get a screenshot of a X window (the window can be covered, not visibled, or minimized).
#include <stdlib.h>
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/X.h>
#include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xrender.h>
int
main ()
{
Display *display = XOpenDisplay (NULL);
XID xid = 90177543; // xdotool search --name "World of Warcraft" | head -1
// Check if Composite extension is enabled
int event_base_return;
int error_base_return;
if (XCompositeQueryExtension (display, &event_base_return, &error_base_return))
printf ("COMPOSITE IS ENABLED!\n");
// Requests the X server to direct the hierarchy starting at window to off-screen storage
XCompositeRedirectWindow (display, xid, CompositeRedirectAutomatic);
// Preventing the backing pixmap from being freed when the window is hidden/destroyed
// If you want the window contents to still be available after the window has been destroyed,
// or after the window has been resized (but not yet redrawn), you can increment the backing
// pixmaps ref count to prevent it from being deallocated.
Pixmap pixmap = XCompositeNameWindowPixmap (display, xid);
// Get window attributes
XWindowAttributes attr;
Status s = XGetWindowAttributes (display, xid, &attr);
if (s == 0)
printf ("Fail to get window attributes!\n");
// Extract the data
XRenderPictFormat *format = XRenderFindVisualFormat (display, attr.visual);
int width = attr.width;
int height = attr.height;
int depth = attr.depth;
// What we need to do now is to create an XRender Picture for the window,
// which we'll need to draw it with the Render extension.
// A picture is a basically a handle to a server side struct with some
// additional information about a drawable (in this case a window),
// such as its format, which clipping region should be used when
// drawing it (if any), whether it should be tiled etc.
XRenderPictureAttributes pa;
pa.subwindow_mode = IncludeInferiors;
Picture picture = XRenderCreatePicture (display, xid, format, CPSubwindowMode, &pa);
// We now have all the information we need in order to be able to draw the window
// using the Xrender extension, and we've created and prepared a source picture
// for the window for this purpose.
// The Xrender function we'll use to draw the window is XRenderComposite().
//XRenderComposite (display, PictOpSrc, picture, None, ???destination???, 0,0, 0,0, 0,0, width, height);
XFreePixmap (display, pixmap);
XCompositeUnredirectWindow (display, xid, CompositeRedirectAutomatic);
return 0;
}
[Compile the code with gcc file.c -lX11 -lXcomposite -lXrender and run with ./a.out]
[You can get a valid XID of a window of your Desktop with the command xdotool search --name "Title of a window" | head -1]
Now I have two problem:
I get a BadMatch (invalid parameter attributes) error when I call the XRenderFindVisualFormat function. I dont know why. The window with XID 90177543 exists.
I don't know how to get the buffer of the Picture picture to save it as a PNG image. I don't want use QT library to do this.
Can you help me?
I am able to reproduce your error as follows:
$ ./xidtest
COMPOSITE IS ENABLED!
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 142 (Composite)
Minor opcode of failed request: 1 ()
Resource id in failed request: 0x5600007
Serial number of failed request: 9
Current serial number in output stream: 12
When set using a window id I knew to exist (0x440000B or 71303179, found using xwininfo), I received no error:
$ ./xidtest
COMPOSITE IS ENABLED!
I conclude that the error is the window id you have provided is invalid.