Not getting resize event - c

First, make a list of the events that I want my window to receive, then I create my
window and after that I run in a while loop this event handler. My goal here is to print hello when the window is resized, and I don't understand why it doesn't. Here is the code :
uint32_t value_list[] = {
XCB_NONE,
XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS |
XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_RESIZE_REDIRECT,
};
xcb_create_window(
result->connection,
XCB_COPY_FROM_PARENT,
result->window,
screen->root,
0, 0, width, height,
0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->root_visual,
XCB_CW_EVENT_MASK,
value_list);
and
if(intern_window->event) {
switch(intern_window->event->response_type & ~0x80) {
case XCB_EXPOSE: {
xcb_flush(intern_window->connection);
break;
}
case XCB_CLIENT_MESSAGE: {
if( ((xcb_client_message_event_t*)intern_window->event)->data.data32[0] == intern_window->delete_reply->atom ) {
intern_window->closing = true;
free(intern_window->delete_reply);
}
break;
}
case XCB_RESIZE_REQUEST: {
puts("Hello");
break;
}
}
}

uint32_t value_list[] = {
XCB_NONE,
XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS |
XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_RESIZE_REDIRECT,
};
xcb_create_window(
result->connection,
XCB_COPY_FROM_PARENT,
result->window,
screen->root,
0, 0, width, height,
0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->root_visual,
XCB_CW_EVENT_MASK,
value_list);
So, value_list[0] is XCB_NONE and value_list[1] is the event mask you want. You then use just XCB_CW_EVENT_MASK, thus value_list[0] is your event mask and value_list[1] is ignored.
You are not getting the events since you did not ask for them.

Related

When i can access to SDL_Rendrerer after maximizing window?

I try to redraw window only when is need, but when window is resize in a hop (for example maximize), SDL_Renderer is not usable in new size some time after action.
Here is my simple example code:
#include <SDL2/SDL.h>
bool redraw = true;
void draw(SDL_Renderer* renderer, SDL_Rect& rect)
{
SDL_SetRenderDrawColor(renderer, 0, 0, 50, 0xFF);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 90, 90, 90, 0xFF);
SDL_RenderDrawLine(renderer, 0, 0, rect.w, rect.h);
SDL_RenderPresent(renderer);
redraw = false;
}
SDL_Rect resize(const SDL_Event& event)
{
int win_w = (int) event.window.data1;
int win_h = (int) event.window.data2;
SDL_Rect rect = {0, 0, win_w, win_h};
redraw = true;
return rect;
}
int main(int argc, char** argv)
{
SDL_Init(SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("Maximize test",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
800, 450, 0);
SDL_SetWindowResizable(window, SDL_TRUE);
SDL_Renderer* renderer = SDL_CreateRenderer(
window, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
bool running = true;
SDL_Event event;
SDL_Rect rect = {0, 0, 800, 450};
while (running) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
running = false;
break;
case SDL_WINDOWEVENT:
switch (event.window.event) {
case SDL_WINDOWEVENT_RESIZED:
rect = resize(event);
break;
}
break;
}
if (redraw) {
draw(renderer, rect);
}
}
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
return 0;
}
At first, I try to get new renderer size SDL_GetRendererOutputSize in same result like getting size from event.
When I try to resize window with typical mouse motion actions, it works fine. But maximize or window manager resizing to one screen side does not work.
I try to use different event like SDL_WINDOWEVENT_SIZE_CHANGED, but with same result.
And yes, normally, I checks all SDL calls, with SDL_RenderDrawLine but without any errors.

C SDL VS Code image is not displaying

I have recently started learning game programming in C. I am using a virtual studio code on linux Ubuntu, and image star.png is not displaying on the screen, there are no errors or problems reported by vs code. I have tried reinstalling sdl2-dev and sdl2-image-dev libraries. Maybe it is a problem with SDL, or maybe with my code (it was written in 2013).
The code should draw a white ractangl, which i can move around, on a blue screen and place a star in upper left corner of a window. It does everything except placing a star.
The code: (doesn't show "Cannot dinf star.png!" so I guess it is not that)
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
typedef struct
{
int x, y;
short life;
char *name;
}Man;
typedef struct
{
//players
Man man;
//image
SDL_Texture *star;
} GameState;
/////////////////////////////////////////////////////////////////////processEvents
int processEvents(SDL_Window *window , GameState *game)
{
SDL_Event event;
int done = 0;
//Check for events
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_WINDOWEVENT_CLOSE:
{
if (window)
{
SDL_DestroyWindow(window);
window = NULL;
done = 1;
}
}
break;
case SDL_KEYDOWN:
{
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
done = 1;
break;
}
}
break;
case SDL_QUIT:
done = 1;
break;
}
}
const Uint8 *state = SDL_GetKeyboardState(NULL);
if(state[SDL_SCANCODE_LEFT])
{
game->man.x -= 1;
}
if(state[SDL_SCANCODE_RIGHT])
{
game->man.x += 1;
}
if(state[SDL_SCANCODE_UP])
{
game->man.y -= 1;
}
if(state[SDL_SCANCODE_DOWN])
{
game->man.y += 1;
}
SDL_Delay(10);
return done;
}
/////////////////////////////////////////////////////////////////////////////////////doRender
void doRedner(SDL_Renderer *renderer, GameState *game)
{
SDL_SetRenderDrawColor(renderer , 0, 0, 255, 255); //blue
//screen clean up into blue
SDL_RenderClear(renderer);
//set color
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_Rect rect = {game->man.x, game->man.y, 80, 80};
SDL_RenderFillRect(renderer, &rect);
//draw a star
SDL_Rect starRect = { 50, 50, 64, 64 };
SDL_RenderCopy(renderer, game->star, NULL, &starRect);
SDL_RenderPresent(renderer);
}
/////////////////////////////////////////////////////////////////////////////////////main funkction
int main(int argc, char *argv[])
{
GameState gameState;
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Surface *starSurface = NULL;
SDL_Init(SDL_INIT_VIDEO);
gameState.man.x = 340-40;
gameState.man.y = 240-40;
window = SDL_CreateWindow("Game Widnow",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
640,
480,
0
);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
//load image
starSurface = IMG_Load("star.png");
if(starSurface = NULL)
{
printf("Cannot find star.png!\n\n");
SDL_Quit();
return 1;
}
gameState.star = SDL_CreateTextureFromSurface(renderer, starSurface);
SDL_FreeSurface(starSurface);
int done = 0;
while(!done)
{
//check events
done = processEvents(window, &gameState);
//render
doRedner(renderer, &gameState);
}
SDL_Delay(1000);
//exit game and free memory
SDL_DestroyTexture(gameState.star);
//destroy and close window
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
return 0;
}
TL;DR: Your intention is to perform a comparison, but you are using the assignment operator (i.e., =) instead of the comparison operator ==.
The conditional expression in your if statement:
if(starSurface = NULL)
{
...
}
does not check whether starSurface is NULL. The expression starSurface = NULL assigns NULL to starSurface and evaluates to NULL. Therefore, the condition evaluates to false and no error message is displayed.
Instead, you should write (note the double = below):
if (starSurface == NULL)
or just:
if (!starSurface)

SDL and C keyboard or touch event

I'm programming in c4droid but I can't get the touch event to work.
Tried switch or if statement but nothing works im sure rendering is ok because if I delete the switch then its renders normally
Here I the code:
#include <SDL2/SDL.h>
int main()
{
SDL_Window *window = NULL;
window = SDL_CreateWindow("Shooter", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
// Setup renderer
SDL_Renderer *renderer = NULL;
renderer = SDL_CreateRenderer(window, 0, SDL_RENDERER_ACCELERATED);
// Set render color to red ( background will be rendered in this color )
SDL_SetRenderDrawColor(renderer, 0, 255, 25, 255);
// Clear winow
SDL_RenderClear(renderer);
// Creat a rect at pos ( 50, 50 ) that's 50 pixels wide and 50 pixels
// high.
SDL_SetRenderDrawColor(renderer, 255, 0, 255, 255);
SDL_Rect r;
r.x = 500;
r.y = 500;
r.w = 50;
r.h = 50;
SDL_Rect e;
e.x = 5;
e.y = 5;
e.w = 50;
e.h = 50;
SDL_Event event;
while(SDL_PollEvent(&event) != 0) {
switch (event.type) {
case SDL_FINGERDOWN :
e.x = e.x + 10;
SDL_RenderFillRect(renderer, &r);
SDL_RenderFillRect(renderer, &e);
SDL_RenderPresent(renderer);
break;
}
}
// Wait for 5 sec
SDL_Delay(50000);
SDL_DestroyWindow(window);
SDL_Quit();
}
You need to make sure to poll the event.
while(true) {
while(SDL_PollEvent(&event) != 0) {
switch (event.type) {
case SDL_FINGERDOWN :
e.x = e.x + 10;
SDL_RenderFillRect(renderer, &r);
SDL_RenderFillRect(renderer, &e);
SDL_RenderPresent(renderer);
break;
// Render rect
}
}
}
Provided event is not NULL, SDL_PollEvent will take the next event from the queue and store it in the SDL_Event that event is pointing at.
Edit: Don't remove the while(true) loop, put this one inside it. Sorry, I probably should have been a bit more clear in the beginning.

X11 XImage manipulation

I'm trying to pick up an image from my brand new window and then draw it back to the same window, just to train on XLib.
Here is my code :
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<X11/Xlib.h>
#include<X11/Xutil.h>
#include<sys/stat.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
int main(int argc, char *argv[]) {
fd_set eventset;
fd_set zeroset;
// struct timeval timeout = {0, 0};
Display *display = 0;
int screen;
Window wnd;
XVisualInfo vinfo;
XSetWindowAttributes attr;
XEvent event;
XImage *bg;
Atom WM_message[2];
int run = 1;
FD_ZERO(&eventset);
FD_ZERO(&zeroset);
if(!(display = XOpenDisplay(0))) {
/* Display not found */
printf("Fail display.\n");
return 0;
}
screen = XDefaultScreen(display);
if(!XMatchVisualInfo(display, screen, 32, TrueColor, &vinfo)) {
if(!XMatchVisualInfo(display, screen, 24, TrueColor, &vinfo)) {
/* No proper color depth available */
XCloseDisplay(display); /* Close X communication */
printf("No found color display. Sorry.\n");
return 0;
}
}
attr.colormap = XCreateColormap(display, DefaultRootWindow(display), vinfo.visual, AllocNone);
attr.border_pixel = 0;
attr.background_pixel = 0x80000000;
attr.bit_gravity = NorthWestGravity;
attr.win_gravity = NorthWestGravity;
wnd = XCreateWindow(display, DefaultRootWindow(display), 0, 0, 300, 300, 0,
vinfo.depth, InputOutput, vinfo.visual,
CWColormap | CWBorderPixel | CWBackPixel | CWBitGravity | CWWinGravity, &attr);
/* Subscribe to window closing event */
WM_message[0] = XInternAtom(display, "WM_PROTOCOLS", 1);
WM_message[1] = XInternAtom(display, "WM_DELETE_WINDOW", 1);
XSetWMProtocols(display, wnd, WM_message, 2);
XFreeColormap(display, attr.colormap);
XSelectInput(display, wnd, ExposureMask | ButtonPressMask | KeyPressMask);
XMapWindow(display, wnd);
bg = XGetImage(display, XDefaultRootWindow(display), 0, 0, 300, 300, AllPlanes, ZPixmap);
// bg = XGetImage(display, wnd, 100, 100, 100, 100, AllPlanes, ZPixmap);
/* int x;
for(x = 0; x < 10000; x++) {
bg->data[x] = 0x80;
} */
XPutImage(display, wnd, XDefaultGC(display, screen), bg, 0, 0, 0, 0, 300, 300);
// XPutImage(display, wnd, XDefaultGC(display, screen), bg, 100, 100, 100, 100, 100, 100);
XMapWindow(display, wnd);
XFlush(display);
while(run) {
XNextEvent(display, &event);
switch(event.type) {
case Expose:
printf("w = %d, h = %d\n", event.xexpose.width, event.xexpose.height);
break;
case DestroyNotify:
run = 0;
break;
case ClientMessage:
{
if(event.xclient.message_type == WM_message[0]) {
if(event.xclient.data.l[0] == WM_message[1]) {
run = 0;
}
}
}
default:;
}
}
XDestroyImage(bg);
XDestroyWindow(display, wnd);
XCloseDisplay(display);
return 0;
}
This crash my program either on porteus and mobaxterm.
But this lines:
// bg = XGetImage(display, wnd, 100, 100, 100, 100, AllPlanes, ZPixmap);
/* int x;
for(x = 0; x < 10000; x++) {
bg->data[x] = 0x80;
} */
// XPutImage(display, wnd, XDefaultGC(display, screen), bg, 100, 100, 100, 100, 100, 100);
Doesn't crash my program... it just render nothing.
Can someone help me understand why do I experiment this weird behavior of X?
This is the error message I am getting:
X Error of failed request: BadMatch (invalid parameter attributes)
Major opcode of failed request: 72 (X_PutImage) Serial number of
failed request: 16 Current serial number in output stream: 18
After further reasearches and tries, I finnally found 2 facts :
First my post is mistaken :
this doesn't crash :
XPutImage(display, XDefaultRootWindow(display), XDefaultGC(display, screen), bg, 100, 100, 100, 100, 100, 100);
Those lines crash :
XPutImage(display, wnd, XDefaultGC(display, screen), bg, 0, 0, 0, 0, 300, 300);
XPutImage(display, wnd, XDefaultGC(display, screen), bg, 100, 100, 100, 100, 100, 100);
Second :
Writing on root window with default gc is alright because default gc is a gc corresponding to the default root window.
But using this GC for my own window is an error since I used color depth that can differ from root window.
So I have now this running well:
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<X11/Xlib.h>
#include<X11/Xutil.h>
#include<sys/stat.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
int main(int argc, char *argv[]) {
fd_set eventset;
fd_set zeroset;
// struct timeval timeout = {0, 0};
Display *display = 0;
int screen;
Window wnd;
XVisualInfo vinfo;
XSetWindowAttributes attr;
XEvent event;
XImage *bg;
GC mainGC;
Atom WM_message[2];
int run = 1;
FD_ZERO(&eventset);
FD_ZERO(&zeroset);
if(!(display = XOpenDisplay(0))) {
/* Display not found */
printf("Fail display.\n");
return 0;
}
screen = XDefaultScreen(display);
if(!XMatchVisualInfo(display, screen, 32, TrueColor, &vinfo)) {
if(!XMatchVisualInfo(display, screen, 24, TrueColor, &vinfo)) {
/* No proper color depth available */
XCloseDisplay(display); /* Close X communication */
printf("No found color display. Sorry.\n");
return 0;
}
}
attr.colormap = XCreateColormap(display, DefaultRootWindow(display), vinfo.visual, AllocNone);
attr.border_pixel = 0;
attr.background_pixel = 0x80000000;
attr.bit_gravity = NorthWestGravity;
attr.win_gravity = NorthWestGravity;
wnd = XCreateWindow(display, DefaultRootWindow(display), 0, 0, 300, 300, 0,
vinfo.depth, InputOutput, vinfo.visual,
CWColormap | CWBorderPixel | CWBackPixel | CWBitGravity | CWWinGravity, &attr);
/* Subscribe to window closing event */
WM_message[0] = XInternAtom(display, "WM_PROTOCOLS", 1);
WM_message[1] = XInternAtom(display, "WM_DELETE_WINDOW", 1);
XSetWMProtocols(display, wnd, WM_message, 2);
XFreeColormap(display, attr.colormap);
XSelectInput(display, wnd, ExposureMask | ButtonPressMask | KeyPressMask);
XMapWindow(display, wnd);
XFlush(display);
mainGC = XCreateGC(display, wnd, 0, 0);
bg = XGetImage(display, wnd, 0, 0, 100, 100, AllPlanes, ZPixmap);
int x;
for(x = 0; x < 10000; x++) {
bg->data[x] = 0x80;
}
XPutImage(display, wnd, mainGC, bg, 0, 0, 100, 100, 100, 100);
while(run) {
XNextEvent(display, &event);
switch(event.type) {
case Expose:
printf("w = %d, h = %d\n", event.xexpose.width, event.xexpose.height);
break;
case DestroyNotify:
run = 0;
break;
case ClientMessage:
{
if(event.xclient.message_type == WM_message[0]) {
if(event.xclient.data.l[0] == WM_message[1]) {
run = 0;
}
}
}
default:;
}
}
XDestroyImage(bg);
XDestroyWindow(display, wnd);
XCloseDisplay(display);
return 0;
}

Preferences Dialog with TreeView and Panel Memory Dialog

I have a options dialogbox with a TreeView and different panel beside that i changed when i select tree item.
My first problem is when the options dialog load the focus is set to the default button even if i remove it.
I want to set focus on the first item in the treeview and keep the focus on.
I tried to set the default id:
SendMessage(hDlgOptions, DM_SETDEFID, IDC_TREE, 0);
I tried to set the focus with the NEXTDLGCTL with no success:
SendMessage(hDlgOptions, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlgOptions, IDC_TREE), TRUE);
My second problem is the animation of window when the options dialog show up the panel is alredy loaded. I want to load it after th animation show.
I set a timer for the moment... Maybe u have a better solution?
Thanks a lot for your expert review i'll take all good ideas for optimising my code too.
Dialog Load
What i want
resource.rc
IDD_DIALOG_OPTIONS DIALOGEX 0, 0, 395, 175
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Options"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "OK",ID_BUTTON_SAVE,338,154,50,14
CONTROL "Save config to ini file",IDC_CHECK_SAVE_CONFIG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,252,156,82,10
CONTROL "",IDC_TREE,"SysTreeView32",TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | TVS_SINGLEEXPAND | WS_HSCROLL | WS_TABSTOP,7,7,98,142
END
IDD_OPTIONS_CONSOLE DIALOGEX 0, 0, 277, 142
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "Take Control",IDC_CHECK_TC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,21,57,10
GROUPBOX "Console",IDC_STATIC_CONSOLE,7,7,134,66
COMBOBOX IDC_COMBO_CONSOLE_COLOR,50,56,85,63,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
LTEXT "Color",IDC_STATIC,17,59,18,8
END
IDD_OPTIONS_GENERAL DIALOGEX 0, 0, 277, 142
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "GENERAL OPTION",IDC_STATIC,89,73,59,8
END
OptionsDialog
//GLOBAL VARIABLES
#define IDT_TIMER_PANEL 77
HWND hDlgOpt;
HWND hDlgPanelGeneral = NULL;
HWND hDlgPanelConsole = NULL;
UINT iPanelSelect = 1;
//HANDLE MESSAGES FROM GENERAL PANEL
LRESULT CALLBACK PanelGeneral(HWND hDlgPanel, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
return TRUE;
}
}
return FALSE;
}
//HANDLE MESSAGES FROM CONSOLE PANEL
LRESULT CALLBACK PanelConsole(HWND hDlgPanel, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
//INIT CONSOLE PANEL CONTROLS
return TRUE;
}
}
return FALSE;
}
//HANDLE MESSAGES FROM OPTIONS DIALOG
LRESULT CALLBACK Options(HWND hDlgOptions, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
hDlgOpt = hDlgOptions;
//LOAD PANEL GENERAL
HRSRC hrsrc = FindResourceEx(hInst, (LPCWSTR)RT_DIALOG, (LPCWSTR)IDD_OPTIONS_GENERAL, iLanguage);
HGLOBAL hglb = LoadResource(hInst, hrsrc);
LPVOID lpsz = LockResource(hglb);
hDlgPanelGeneral = CreateDialogIndirectW(GetModuleHandleW(NULL), lpsz, hDlgOptions, (DLGPROC)PanelGeneral);
//LOAD PANEL CONSOLE
hrsrc = FindResourceEx(hInst, (LPCWSTR)RT_DIALOG, (LPCWSTR)IDD_OPTIONS_CONSOLE, iLanguage);
hglb = LoadResource(hInst, hrsrc);
lpsz = LockResource(hglb);
hDlgPanelConsole = CreateDialogIndirectW(GetModuleHandleW(NULL), lpsz, hDlgOptions, (DLGPROC)PanelConsole);
//Await the animation window for displaying TreeView and Panel
SetTimer(hDlgOptions, IDT_TIMER_PANEL, 300, (TIMERPROC) NULL);
//TRY TO SET DEFAUT ID TO TREEVIEW
//SendMessage(hDlgOptions, DM_SETDEFID, IDC_TREE, 0);
//TRY TO FOCUS ON TREEVIEW
//SendMessage(hDlgOptions, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlgOptions, IDC_TREE), TRUE);
//INIT CONTROLS
if (bSaveConfig == TRUE)
{
EnableOptionsControls(hDlgPanelConsole);
SendMessage(GetDlgItem(hDlgOptions, IDC_CHECK_SAVE_CONFIG), BM_SETCHECK, BST_CHECKED, 0);
}
else
{
DisableOptionsControls(hDlgPanelConsole);
}
return TRUE;
}
case WM_NOTIFY:
{
switch (LOWORD(wParam))
{
case IDC_TREE:
NotifyTreeView(hDlgOptions, lParam, wParam);
break;
}
return TRUE;
}
case WM_MOVE:
{
//MAYBE ONLY USE WM_MOVING
UINT xPos = (UINT)LOWORD(lParam);
UINT yPos = (UINT)HIWORD(lParam);
SetWindowPos(hDlgPanelGeneral, HWND_TOP, xPos + 162, yPos + 11, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
SetWindowPos(hDlgPanelConsole, HWND_TOP, xPos + 162, yPos + 11, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
switch (iPanelSelect)
{
case 1: ShowWindow(hDlgPanelGeneral, SW_SHOW); break;
case 2: ShowWindow(hDlgPanelConsole, SW_SHOW); break;
}
return TRUE;
}
case WM_MOVING:
{
//MAYBE BEST MOVING PANEL WITH THE DIALOG
//BUT WIN7 HIDE THE CONTENT...
//NOW HIDE WHEN MOVING
ShowWindow(hDlgPanelGeneral, SW_HIDE);
ShowWindow(hDlgPanelConsole, SW_HIDE);
return TRUE;
}
case WM_TIMER:
{
switch (wParam)
{
case IDT_TIMER_PANEL:
//LOAD TREEVIEW
InitTreeView(hDlgOptions);
KillTimer(hDlgOptions, IDT_TIMER_PANEL);
}
return FALSE;
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case ID_BUTTON_SAVE:
case IDOK:
case IDCANCEL:
{
EndDialog(hDlgOptions, LOWORD(wParam));
return TRUE;
}
break;
}
}
}
return FALSE;
}
void EnableOptionsControls(HWND hDlgOptions)
{
EnableWindow(GetDlgItem(hDlgOptions, IDC_CHECK_TC), TRUE);
EnableWindow(GetDlgItem(hDlgOptions, IDC_COMBO_CONSOLE_COLOR), TRUE);
}
void DisableOptionsControls(HWND hDlgOptions)
{
EnableWindow(GetDlgItem(hDlgOptions, IDC_CHECK_TC), FALSE);
EnableWindow(GetDlgItem(hDlgOptions, IDC_COMBO_CONSOLE_COLOR), FALSE);
}
void InitTreeView(HWND hDlgOptions)
{
TV_INSERTSTRUCT tviis;
HTREEITEM hitem;
HIMAGELIST hImageList;
HWND hTreeView;
hTreeView = GetDlgItem(hDlgOptions, IDC_TREE);
hImageList = ImageList_LoadImage(hInst, MAKEINTRESOURCE(IDB_BITMAP_TV), 16, 16,
CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_DEFAULTCOLOR);
TreeView_SetImageList(hTreeView, hImageList, TVSIL_NORMAL);
ZeroMemory(&(tviis.item), sizeof(TV_ITEM));
tviis.hInsertAfter = TVI_LAST;
tviis.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
tviis.hParent = TVI_ROOT;
tviis.item.iImage = 0;
tviis.item.iSelectedImage = 1;
tviis.item.lParam = 1;
tviis.item.pszText = L"General";
hitem = TreeView_InsertItem(hTreeView, &tviis);
tviis.hParent = hitem;
tviis.item.iImage = 2;
tviis.item.iSelectedImage = 2;
tviis.item.lParam = 3;
tviis.item.pszText = L"Dialog";
TreeView_InsertItem(hTreeView, &tviis);
tviis.item.iImage = 3;
tviis.item.iSelectedImage = 3;
tviis.item.lParam = 4;
tviis.item.pszText = L"Color";
TreeView_InsertItem(hTreeView, &tviis);
//SELECT THE FIRST ITEM
TreeView_SelectItem(hTreeView, hitem);
TreeView_Expand(hTreeView, hitem, TVE_EXPAND);
tviis.hParent = TVI_ROOT;
tviis.item.iImage = 0;
tviis.item.iSelectedImage = 1;
tviis.item.lParam = 2;
tviis.item.pszText = L"Console";
hitem = TreeView_InsertItem(hTreeView, &tviis);
tviis.hParent = hitem;
tviis.item.iImage = 3;
tviis.item.iSelectedImage = 3;
tviis.item.lParam = 5;
tviis.item.pszText = L"Color";
TreeView_InsertItem(hTreeView, &tviis);
tviis.item.iSelectedImage = 2;
tviis.item.iImage = 2;
tviis.item.lParam = 6;
tviis.item.pszText = L"Action";
TreeView_InsertItem(hTreeView, &tviis);
}
void NotifyTreeView(HWND hDlgOptions, LPARAM lParam, WPARAM wParam)
{
LPNMTREEVIEW pnm = (LPNMTREEVIEW)lParam;
//NOTIFY WHEN SELECTION IS CHANGE
if (((LPNMHDR)lParam)->code == TVN_SELCHANGED)
{
RECT wRECT;
GetWindowRect(hDlgOptions, &wRECT);
TVITEM tvi;
HTREEITEM Selected = NULL;
WCHAR Text[255] = { 0 };
Selected = TreeView_GetSelection(GetDlgItem(hDlgOptions, IDC_TREE));
if (Selected == NULL)
return;
ZeroMemory(&tvi, sizeof(tvi));
tvi.mask = TVIF_TEXT;
tvi.pszText = Text;
tvi.cchTextMax = 256;
tvi.hItem = Selected;
//CHANGE THE PANEL WITH THE SELECT ITEM
if (TreeView_GetItem(GetDlgItem(hDlgOptions, IDC_TREE), &tvi))
{
if (wcscmp(tvi.pszText, L"General") == 0)
{
iPanelSelect = 1;
ShowWindow(hDlgPanelConsole, SW_HIDE);
SetWindowPos(hDlgPanelGeneral, HWND_TOP, wRECT.left + 165, wRECT.top + 36, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
return;
}
if (wcscmp(tvi.pszText, L"Console") == 0)
{
iPanelSelect = 2;
ShowWindow(hDlgPanelGeneral, SW_HIDE);
SetWindowPos(hDlgPanelConsole, HWND_TOP, wRECT.left + 165, wRECT.top + 36, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
return;
}
}
}
}
The tab order is defined by the order your controls are listed in the rc file. Just move your
CONTROL "",IDC_TREE,...
line to be the first after BEGIN.
I am not sure what animation are you talking about. The timer is an OK way to delay something if there is a specific time interval. If you simply want to defer initialization of the Tree control until after everything is created and displayed, I would post some command message, and do everything in its handler.

Resources