Hi all,
I know I am no licensed and use the free home edition for developping. Maybe this forum is more a support for people holding a full membership (which d be fair), but I would be more than gratefull if someone could help me with this issue on writing GUI plugin with winapi.
Few weeks ago, I ve been having troubles getting a tab control changing between tabs. So I went for overlayed listboxes and radiobuttons that get those listboxes visible/hidden. But just realised that the problem lies in the fact that the GUI never repaint after the plugin is started, even if I explicitly call a Updatewindow...
Maybe I am missing something on managing the Winproc (although I get all the messages sent by the GUI, e.g. when clicking on radiobuttons etc...).
Please if someone has experienced the same situation please , your help would be really great.
Cheers,
Alou
I know I am no licensed and use the free home edition for developping. Maybe this forum is more a support for people holding a full membership (which d be fair), but I would be more than gratefull if someone could help me with this issue on writing GUI plugin with winapi.
Few weeks ago, I ve been having troubles getting a tab control changing between tabs. So I went for overlayed listboxes and radiobuttons that get those listboxes visible/hidden. But just realised that the problem lies in the fact that the GUI never repaint after the plugin is started, even if I explicitly call a Updatewindow...
Maybe I am missing something on managing the Winproc (although I get all the messages sent by the GUI, e.g. when clicking on radiobuttons etc...).
Please if someone has experienced the same situation please , your help would be really great.
Cheers,
Alou
Posted Sat 12 Oct 13 @ 1:46 pm
Never had any problem with redrawing GUI elements myself, probably going to be easiest if we can see your code.
Posted Mon 14 Oct 13 @ 9:59 am
Thanks SBDJ for reply.
Here is the implementation of my GUI class:
===============================================================================
[code language="cpp"]
#include "DJ4Me_gui.h"
LRESULT CALLBACK DJ4Me_gui::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
DJ4Me_gui* This = (DJ4Me_gui*)GetWindowLongPtr(hwnd,GWL_USERDATA);
HDC hdc;
//wchar_t buffer[200];
//wsprintf(buffer, L"%d", LOWORD(wParam));
//MessageBox(0,buffer, L"Title", MB_OK);
PAINTSTRUCT ps;
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
//wchar_t buf[512];
//swprintf(buf, L"%d,%d,%d,%d\n%d", ps.rcPaint.top, ps.rcPaint.left,ps.rcPaint.right,ps.rcPaint.bottom,ps.fErase);
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
EndPaint(hwnd, &ps);
break;
case WM_COMMAND:
wchar_t buffer[200];
wsprintf(buffer, L"%d", LOWORD(wParam));
switch(LOWORD(wParam))
{
case RADIO_BUTTON_VAL_1 :
This->_currentTab = This->_listBox1;
ShowWindow(This->_listBox1, SW_SHOW);
ShowWindow(This->_listBox2, SW_HIDE);
//UpdateWindow(hwnd);
break;
case RADIO_BUTTON_VAL_2:
This->_currentTab = This->_listBox2;
ShowWindow(This->_listBox2, SW_SHOW);
ShowWindow(This->_listBox1, SW_HIDE);
//UpdateWindow(hwnd);
break;
}
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
break;
}
}
DJ4Me_gui::DJ4Me_gui(HINSTANCE hInstance)
{
this->the_instance = hInstance;
init_win(hInstance);
this->create_toolbar();
this->create_group_box();
this->create_listbox();
this->resize();
SetCursor(LoadCursor(NULL, IDC_ARROW));
SetWindowLongPtr(the_handle, GWL_USERDATA, (LONG)this);
}
int DJ4Me_gui::init_win(HINSTANCE hInstance)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"dj4me_gui";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
NULL, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
the_handle = hwnd;
return 1;
}
int DJ4Me_gui::resize()
{
//Getting the toolbar size
RECT rect;
GetClientRect(_toolBar, &rect);
int height_t = rect.bottom - rect.top;
//Getting the windows size
GetClientRect(the_handle, &rect);
int width_w = rect.right - rect.left;
int height_w = rect.bottom - rect.top;
SetWindowPos(_groupBox, NULL,0, height_t + 5, width_w, 50,SWP_SHOWWINDOW);
//Getting the group_box size
GetClientRect(_groupBox,&rect);
int height_g = rect.bottom - rect.top;
SetWindowPos(_radioButton1 ,NULL, rect.left + 5 , height_t + 5 + rect.top + 15 , 150 , 30 ,SWP_SHOWWINDOW );
SetWindowPos(_radioButton2 ,NULL, rect.left + 160, height_t + 5 + rect.top + 15 , 200 , 30 ,SWP_SHOWWINDOW );
int top_l = height_t + 5 + height_g + 10;
int list_vis1 = SWP_SHOWWINDOW | SWP_NOZORDER;
int list_vis2 = SWP_HIDEWINDOW | SWP_NOZORDER;
if(this->_currentTab == _listBox2){
list_vis2 = SWP_SHOWWINDOW | SWP_NOZORDER;
list_vis1 = SWP_HIDEWINDOW | SWP_NOZORDER;
}
SetWindowPos(_listBox1, NULL, rect.left + 5 , top_l , width_w , height_w - top_l , list_vis1/*SWP_NOMOVE|SWP_NOZORDER*/ );
SetWindowPos(_listBox2, NULL, rect.left + 5 , top_l , width_w , height_w - top_l , list_vis2/*SWP_NOMOVE|SWP_NOZORDER*/ );
return 1;
}
int DJ4Me_gui::create_toolbar()
{
HIMAGELIST g_hImageList = NULL;
// Declare and initialize local constants.
const int ImageListID = 0;
const int numButtons = 3;
const int bitmapSize = 16;
const DWORD buttonStyles = BTNS_AUTOSIZE;
// Create the toolbar.
HWND hWndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
WS_CHILD | TBSTYLE_WRAPABLE, 0, 0, 0, 0,
the_handle, (HMENU)TOOL_BAR_VAL, the_instance, NULL);
if (hWndToolbar == NULL)
return NULL;
// Create the image list.
g_hImageList = ImageList_Create(bitmapSize, bitmapSize, // Dimensions of individual bitmaps.
ILC_COLOR16 | ILC_MASK, // Ensures transparent background.
numButtons, 0);
// Set the image list.
SendMessage(hWndToolbar, TB_SETIMAGELIST,
(WPARAM)ImageListID,
(LPARAM)g_hImageList);
// Load the button images.
SendMessage(hWndToolbar, TB_LOADIMAGES,
(WPARAM)IDB_STD_SMALL_COLOR,
(LPARAM)HINST_COMMCTRL);
// Initialize button info.
// IDM_NEW, IDM_OPEN, and IDM_SAVE are application-defined command constants.
TBBUTTON tbButtons[numButtons] =
{
{ MAKELONG(STD_FILENEW, ImageListID), IDM_NEW, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"New" },
{ MAKELONG(STD_FILEOPEN, ImageListID), IDM_OPEN, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"Open"},
{ MAKELONG(STD_FILESAVE, ImageListID), IDM_SAVE, 0, buttonStyles, {0}, 0, (INT_PTR)L"Save"}
};
// Add buttons.
SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
SendMessage(hWndToolbar, TB_ADDBUTTONS, (WPARAM)numButtons, (LPARAM)&tbButtons);
// Resize the toolbar, and then show it.
SendMessage(hWndToolbar, TB_AUTOSIZE, 0, 0);
ShowWindow(hWndToolbar, TRUE);
_toolBar = hWndToolbar;
return 1;
}
int DJ4Me_gui::create_group_box(){
_groupBox = CreateWindowEx(WS_EX_WINDOWEDGE,
L"BUTTON",
L"Select List",
WS_VISIBLE | WS_CHILD|BS_GROUPBOX,// <----BS_GROUPBOX does nothing on the grouping
0,0,0,0,
the_handle,
NULL,
the_instance, NULL);
_radioButton1 = CreateWindowEx(WS_EX_WINDOWEDGE,
L"BUTTON",
L"Available Songs",
WS_VISIBLE | WS_CHILD|BS_AUTORADIOBUTTON|WS_GROUP, // <---- WS_GROUP group the following radio buttons 1st,2nd button
0,0,0,0,
the_handle, //<----- Use main window handle
(HMENU)RADIO_BUTTON_VAL_1,
the_instance, NULL);
Button_SetCheck(_radioButton1,BST_CHECKED);
_radioButton2 = CreateWindowEx(WS_EX_WINDOWEDGE,
L"BUTTON",
L"List of Requested Songs",
WS_VISIBLE | WS_CHILD|BS_AUTORADIOBUTTON, // Styles
0,0,0,0,
the_handle,
(HMENU)RADIO_BUTTON_VAL_2,
the_instance, NULL);
return 1;
}
int DJ4Me_gui::create_listbox()
{
HWND hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, L"Listbox", NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
LBS_DISABLENOSCROLL | LBS_SORT,
0, 0, 0, 0, the_handle, (HMENU)1002,
the_instance, NULL);
if (hwnd == NULL)
{
return NULL;
}
_listBox1 = hwnd;
SendMessage(_listBox1, LB_ADDSTRING, 0, (LPARAM)L"Martyn.Rae");
HWND hwnd1 = CreateWindowEx(WS_EX_CLIENTEDGE, L"Listbox", NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
LBS_DISABLENOSCROLL | LBS_SORT,
0, 0, 0, 0, the_handle, (HMENU)1003,
the_instance, NULL);
if (hwnd1 == NULL)
{
return NULL;
}
_listBox2 = hwnd1;
SendMessage(_listBox2, LB_ADDSTRING, 0, (LPARAM)L"Alou.seck");
return 1;
}
[/code]
================================================================================
And here is my Plugin implementation
================================================================================
[code language="cpp"]
HRESULT __stdcall DllGetClassObject(const GUID &rclsid,const GUID &riid,void** ppObject)
{
if (memcmp(&rclsid,&CLSID_VdjPlugin6,sizeof(GUID))==0 && memcmp(&riid,&IID_IVdjPluginDsp,sizeof(GUID))==0){
*ppObject = new Cdj4meApp();
}
else
{
return CLASS_E_CLASSNOTAVAILABLE;
}
return NO_ERROR;
}
HRESULT __stdcall Cdj4meApp::OnGetUserInterface(HWND *hWnd)
{
DJ4Me_gui win(hInstance);
*hWnd = win.the_handle;
return S_OK;
}
HRESULT __stdcall Cdj4meApp::OnLoad()
{
return 0;
}
HRESULT __stdcall Cdj4meApp::OnGetPluginInfo(TVdjPluginInfo *infos)
{
return 0;
}
HRESULT __stdcall Cdj4meApp::OnStart(int, int)
{
return 0;
}
[/code]
===============================================================================
Here is the implementation of my GUI class:
===============================================================================
[code language="cpp"]
#include "DJ4Me_gui.h"
LRESULT CALLBACK DJ4Me_gui::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
DJ4Me_gui* This = (DJ4Me_gui*)GetWindowLongPtr(hwnd,GWL_USERDATA);
HDC hdc;
//wchar_t buffer[200];
//wsprintf(buffer, L"%d", LOWORD(wParam));
//MessageBox(0,buffer, L"Title", MB_OK);
PAINTSTRUCT ps;
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
//wchar_t buf[512];
//swprintf(buf, L"%d,%d,%d,%d\n%d", ps.rcPaint.top, ps.rcPaint.left,ps.rcPaint.right,ps.rcPaint.bottom,ps.fErase);
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
EndPaint(hwnd, &ps);
break;
case WM_COMMAND:
wchar_t buffer[200];
wsprintf(buffer, L"%d", LOWORD(wParam));
switch(LOWORD(wParam))
{
case RADIO_BUTTON_VAL_1 :
This->_currentTab = This->_listBox1;
ShowWindow(This->_listBox1, SW_SHOW);
ShowWindow(This->_listBox2, SW_HIDE);
//UpdateWindow(hwnd);
break;
case RADIO_BUTTON_VAL_2:
This->_currentTab = This->_listBox2;
ShowWindow(This->_listBox2, SW_SHOW);
ShowWindow(This->_listBox1, SW_HIDE);
//UpdateWindow(hwnd);
break;
}
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
break;
}
}
DJ4Me_gui::DJ4Me_gui(HINSTANCE hInstance)
{
this->the_instance = hInstance;
init_win(hInstance);
this->create_toolbar();
this->create_group_box();
this->create_listbox();
this->resize();
SetCursor(LoadCursor(NULL, IDC_ARROW));
SetWindowLongPtr(the_handle, GWL_USERDATA, (LONG)this);
}
int DJ4Me_gui::init_win(HINSTANCE hInstance)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"dj4me_gui";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
NULL, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
the_handle = hwnd;
return 1;
}
int DJ4Me_gui::resize()
{
//Getting the toolbar size
RECT rect;
GetClientRect(_toolBar, &rect);
int height_t = rect.bottom - rect.top;
//Getting the windows size
GetClientRect(the_handle, &rect);
int width_w = rect.right - rect.left;
int height_w = rect.bottom - rect.top;
SetWindowPos(_groupBox, NULL,0, height_t + 5, width_w, 50,SWP_SHOWWINDOW);
//Getting the group_box size
GetClientRect(_groupBox,&rect);
int height_g = rect.bottom - rect.top;
SetWindowPos(_radioButton1 ,NULL, rect.left + 5 , height_t + 5 + rect.top + 15 , 150 , 30 ,SWP_SHOWWINDOW );
SetWindowPos(_radioButton2 ,NULL, rect.left + 160, height_t + 5 + rect.top + 15 , 200 , 30 ,SWP_SHOWWINDOW );
int top_l = height_t + 5 + height_g + 10;
int list_vis1 = SWP_SHOWWINDOW | SWP_NOZORDER;
int list_vis2 = SWP_HIDEWINDOW | SWP_NOZORDER;
if(this->_currentTab == _listBox2){
list_vis2 = SWP_SHOWWINDOW | SWP_NOZORDER;
list_vis1 = SWP_HIDEWINDOW | SWP_NOZORDER;
}
SetWindowPos(_listBox1, NULL, rect.left + 5 , top_l , width_w , height_w - top_l , list_vis1/*SWP_NOMOVE|SWP_NOZORDER*/ );
SetWindowPos(_listBox2, NULL, rect.left + 5 , top_l , width_w , height_w - top_l , list_vis2/*SWP_NOMOVE|SWP_NOZORDER*/ );
return 1;
}
int DJ4Me_gui::create_toolbar()
{
HIMAGELIST g_hImageList = NULL;
// Declare and initialize local constants.
const int ImageListID = 0;
const int numButtons = 3;
const int bitmapSize = 16;
const DWORD buttonStyles = BTNS_AUTOSIZE;
// Create the toolbar.
HWND hWndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
WS_CHILD | TBSTYLE_WRAPABLE, 0, 0, 0, 0,
the_handle, (HMENU)TOOL_BAR_VAL, the_instance, NULL);
if (hWndToolbar == NULL)
return NULL;
// Create the image list.
g_hImageList = ImageList_Create(bitmapSize, bitmapSize, // Dimensions of individual bitmaps.
ILC_COLOR16 | ILC_MASK, // Ensures transparent background.
numButtons, 0);
// Set the image list.
SendMessage(hWndToolbar, TB_SETIMAGELIST,
(WPARAM)ImageListID,
(LPARAM)g_hImageList);
// Load the button images.
SendMessage(hWndToolbar, TB_LOADIMAGES,
(WPARAM)IDB_STD_SMALL_COLOR,
(LPARAM)HINST_COMMCTRL);
// Initialize button info.
// IDM_NEW, IDM_OPEN, and IDM_SAVE are application-defined command constants.
TBBUTTON tbButtons[numButtons] =
{
{ MAKELONG(STD_FILENEW, ImageListID), IDM_NEW, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"New" },
{ MAKELONG(STD_FILEOPEN, ImageListID), IDM_OPEN, TBSTATE_ENABLED, buttonStyles, {0}, 0, (INT_PTR)L"Open"},
{ MAKELONG(STD_FILESAVE, ImageListID), IDM_SAVE, 0, buttonStyles, {0}, 0, (INT_PTR)L"Save"}
};
// Add buttons.
SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
SendMessage(hWndToolbar, TB_ADDBUTTONS, (WPARAM)numButtons, (LPARAM)&tbButtons);
// Resize the toolbar, and then show it.
SendMessage(hWndToolbar, TB_AUTOSIZE, 0, 0);
ShowWindow(hWndToolbar, TRUE);
_toolBar = hWndToolbar;
return 1;
}
int DJ4Me_gui::create_group_box(){
_groupBox = CreateWindowEx(WS_EX_WINDOWEDGE,
L"BUTTON",
L"Select List",
WS_VISIBLE | WS_CHILD|BS_GROUPBOX,// <----BS_GROUPBOX does nothing on the grouping
0,0,0,0,
the_handle,
NULL,
the_instance, NULL);
_radioButton1 = CreateWindowEx(WS_EX_WINDOWEDGE,
L"BUTTON",
L"Available Songs",
WS_VISIBLE | WS_CHILD|BS_AUTORADIOBUTTON|WS_GROUP, // <---- WS_GROUP group the following radio buttons 1st,2nd button
0,0,0,0,
the_handle, //<----- Use main window handle
(HMENU)RADIO_BUTTON_VAL_1,
the_instance, NULL);
Button_SetCheck(_radioButton1,BST_CHECKED);
_radioButton2 = CreateWindowEx(WS_EX_WINDOWEDGE,
L"BUTTON",
L"List of Requested Songs",
WS_VISIBLE | WS_CHILD|BS_AUTORADIOBUTTON, // Styles
0,0,0,0,
the_handle,
(HMENU)RADIO_BUTTON_VAL_2,
the_instance, NULL);
return 1;
}
int DJ4Me_gui::create_listbox()
{
HWND hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, L"Listbox", NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
LBS_DISABLENOSCROLL | LBS_SORT,
0, 0, 0, 0, the_handle, (HMENU)1002,
the_instance, NULL);
if (hwnd == NULL)
{
return NULL;
}
_listBox1 = hwnd;
SendMessage(_listBox1, LB_ADDSTRING, 0, (LPARAM)L"Martyn.Rae");
HWND hwnd1 = CreateWindowEx(WS_EX_CLIENTEDGE, L"Listbox", NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
LBS_DISABLENOSCROLL | LBS_SORT,
0, 0, 0, 0, the_handle, (HMENU)1003,
the_instance, NULL);
if (hwnd1 == NULL)
{
return NULL;
}
_listBox2 = hwnd1;
SendMessage(_listBox2, LB_ADDSTRING, 0, (LPARAM)L"Alou.seck");
return 1;
}
[/code]
================================================================================
And here is my Plugin implementation
================================================================================
[code language="cpp"]
HRESULT __stdcall DllGetClassObject(const GUID &rclsid,const GUID &riid,void** ppObject)
{
if (memcmp(&rclsid,&CLSID_VdjPlugin6,sizeof(GUID))==0 && memcmp(&riid,&IID_IVdjPluginDsp,sizeof(GUID))==0){
*ppObject = new Cdj4meApp();
}
else
{
return CLASS_E_CLASSNOTAVAILABLE;
}
return NO_ERROR;
}
HRESULT __stdcall Cdj4meApp::OnGetUserInterface(HWND *hWnd)
{
DJ4Me_gui win(hInstance);
*hWnd = win.the_handle;
return S_OK;
}
HRESULT __stdcall Cdj4meApp::OnLoad()
{
return 0;
}
HRESULT __stdcall Cdj4meApp::OnGetPluginInfo(TVdjPluginInfo *infos)
{
return 0;
}
HRESULT __stdcall Cdj4meApp::OnStart(int, int)
{
return 0;
}
[/code]
===============================================================================
Posted Mon 14 Oct 13 @ 11:41 am
Sorry, couldn t find a way to format my code on the forum.
Posted Mon 14 Oct 13 @ 11:49 am