GUI - unable to add columns to a ListView - c++

I want to add columns to a ListView control. You can see what I tried below using ListView_InsertColumn, but I'm getting "identifier x is undefined". It should be in CommCtrl.h, but I don't know what's wrong. I've seen some people using CListView_InsertColumn instead. Not sure what the difference is.
#include <Windows.h>
#include "resource.h"
#pragma comment(linker, "\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
#include <CommCtrl.h> // LV_COLUMN and ListView_x
INT_PTR CALLBACK DialogProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_INITDIALOG:
LVCOLUMNW col;
col.mask = LVCF_TEXT | LVCF_WIDTH | LVIF_IMAGE;
col.cx = 40;
ListView_InsertColumn(GetDlgItem(hWnd, IDC_LIST2), 0, &col);
return TRUE;
case WM_NCDESTROY:
PostQuitMessage(0);
return FALSE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
case IDCANCEL:
DestroyWindow(hWnd);
break;
default:
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
int WINAPI WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nShowCmd
)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
HWND hWnd = CreateDialogParamW(hInstance, MAKEINTRESOURCEW(IDD_MAIN), nullptr, &DialogProc, 0);
if (!hWnd)
{
MessageBoxW(nullptr, L"Dialog Creation Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hWnd, nShowCmd);
UpdateWindow(hWnd);
MSG msg;
while (GetMessageW(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return msg.wParam;
}
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_MAIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 302
TOPMARGIN, 7
BOTTOMMARGIN, 169
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_MAIN DIALOGEX 0, 0, 309, 176
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Test"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LISTBOX IDC_LIST2,29,44,235,56,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
END
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_MAIN AFX_DIALOG_LAYOUT
BEGIN
0
END
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

As mentioned in the comments, the control you define in your resource script is a ListBox, not a ListView. For the latter, you'll need to use the generic CONTROL statement with a control class of "SysListView32" (this can be inserted from the Visual Resource Editor as a "List Control" object, with its "View" property set to "Report"). Note: Without the LVS_REPORT style, you can't add columns to your control.
Here's a suggested replacement for the dialog resource you have:
IDD_MAIN DIALOGEX 0, 0, 309, 176
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Test"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
//LISTBOX IDC_LIST2, 29, 44, 235, 56, LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
CONTROL "", IDC_LIST2, "SysListView32", LVS_REPORT | LVS_SORTASCENDING | WS_VSCROLL | WS_TABSTOP,
29, 44, 235, 56
END
With only that change made, your program will crash/hang during the call to ListView_InsertColumn, because you have specified the LVCF_WIDTH and LVCF_IMAGE flags in the mask member of the LVCOLUMN structure but have not provided valid data for those flags. I can't just 'invent' an image for you but, with some 'dummy' text values (and an extra column, for good measure), here's a suggestion for some 'fixed' code:
switch (Message) {
case WM_INITDIALOG: {
wchar_t c0txt[] = L"abc-0";
LVCOLUMNW col;
col.mask = LVCF_TEXT | LVCF_WIDTH;// | LVIF_IMAGE;
col.cx = 40;
col.pszText = c0txt;
ListView_InsertColumn(GetDlgItem(hWnd, IDC_LIST2), 0, &col);
// Add another column...
wchar_t c1txt[] = L"xyz-1";
col.mask = LVCF_TEXT | LVCF_WIDTH;// | LVIF_IMAGE;
col.cx = 80;
col.pszText = c1txt;
ListView_InsertColumn(GetDlgItem(hWnd, IDC_LIST2), 1, &col);
return TRUE;
}
When building your code with just the changes outlined above, I get a list view control with two columns:

Related

WinAPI GUI: Is Status Bar possible with dialog box?

I'm using dialog box-based Win API C++ GUI. Just read the docs and there is CreateStatusWindow API which is used to create the status bar, but I don't know how it can be fit into mine, because I'm using CreateDialogW.
CreateStatusWindow is obsolete, CreateWindow is recommended.
Note This function is obsolete. Use CreateWindow instead
#include <Windows.h>
#include "resource.h"
// Enable Visual Styles
#pragma comment(linker, "\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
// Set Windows GUI Subsystem
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
// Required for LV_COLUMN and ListView_x
#include <CommCtrl.h>
INT_PTR CALLBACK DialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
{
// Load icon
const auto icon = static_cast<HICON>(LoadImageW(GetModuleHandleW(nullptr), MAKEINTRESOURCEW(IDI_ICON1), IMAGE_ICON, 64, 64, 0));
SendMessageW(hWnd, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(icon));
// Load menu
const HMENU menu = LoadMenuW(GetModuleHandleW(nullptr), MAKEINTRESOURCEW(IDR_MENU1));
SetMenu(hWnd, menu);
// Add ListView columns
LVCOLUMNW col{};
col.mask = LVCF_TEXT | LVCF_WIDTH | LVIF_IMAGE;
col.cx = 60;
wchar_t c0_txt[] = L"Title";
col.pszText = c0_txt;
ListView_InsertColumn(GetDlgItem(hWnd, IDC_LIST1), 0, &col);
return TRUE;
}
case WM_NCDESTROY:
PostQuitMessage(0);
return FALSE;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDOK:
case IDCANCEL:
DestroyWindow(hWnd);
break;
default:
break;
}
return FALSE; // we didn't handle that particular `msg` completely, therefore we should return FALSE. It can also depend on `wParam` and `lParam`.
}
default:
return FALSE;
}
}
int WINAPI WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nShowCmd
)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
HWND hWnd = CreateDialogParamW(hInstance, MAKEINTRESOURCEW(IDD_MAIN), nullptr, &DialogProc, 0);
if (!hWnd)
{
MessageBoxW(nullptr, L"Dialog Creation Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hWnd, nShowCmd);
UpdateWindow(hWnd);
MSG msg;
while (GetMessageW(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return msg.wParam;
}
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_MAIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 448
TOPMARGIN, 7
BOTTOMMARGIN, 213
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_MAIN DIALOGEX 0, 0, 455, 220
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Test"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,21,25,396,160
END
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_MAIN AFX_DIALOG_LAYOUT
BEGIN
0
END
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MENU1 MENU
BEGIN
POPUP "Control Panel"
BEGIN
MENUITEM "Exit", ID_CONTROLPANEL_EXIT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON "Hopstarter-Sleek-Xp-Basic-Folder.ico"
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
Edit (Fixed the chinese characters):
I was able to add it on WM_INITDIALOG, but unfortunately it doesn't resize along with the window's resizing and its encoding is chinese.
// Add Status Bar
RECT client_rect{};
GetClientRect(hWnd, &client_rect);
HWND status = CreateWindowExW(0, STATUSCLASSNAMEW, nullptr, WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0,
client_rect.bottom - client_rect.top - 20,
client_rect.right - client_rect.left, 20, hWnd, nullptr, hInstance,
nullptr);
int status_parts[2] = { client_rect.right - client_rect.left - 170,
client_rect.right - client_rect.left };
SendMessageW(status, SB_SETPARTS, 2, reinterpret_cast<LPARAM>(&status_parts));
SendMessageW(status, SB_SETTEXT, 0, reinterpret_cast<LPARAM>(L"Test"));
SendMessageW(status, WM_SIZE, 0, 0);
When creating a dialog from a resource template the system sends a WM_INITDIALOG message to the dialog procedure:
Sent to the dialog box procedure immediately before a dialog box is displayed. Dialog box procedures typically use this message to initialize controls and carry out any other initialization tasks that affect the appearance of the dialog box.
If a dialog needs a dynamically created Status Bar control, that's where it should be created. Since
the window procedure for the status bar automatically sets the initial size and position of the window, ignoring the values specified in the CreateWindowEx function
you can pass arbitrary values for x, y, width, and height:
case WM_INITDIALOG:
CreateWindowExW(0, STATUSCLASSNAMEW, nullptr, WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
0, 0, 0, 0, hWnd,
reinterpret_cast<HMENU>(IDC_STATUS_BAR), GetModuleHandleW(nullptr), nullptr);
return TRUE;
For this to compile you will have to create a symbolic constant IDC_STATUS_BAR to act as a control identifier (used later when resizing). One way is to add it to the resource.h file, e.g.:
#define IDC_STATUS_BAR 101
That creates a properly positioned and sized status bar control. Instructions on how to keep it in the desired relative position when its parent is resized are documented as well:
The window procedure [for the status bar] automatically adjusts the size of the status bar whenever it receives a WM_SIZE message. Typically, when the size of the parent window changes, the parent sends a WM_SIZE message to the status bar.
Again, the status bar control ignores the width and height, so sending a WM_SIZE message with arbitrary values is fine. Add the following to the dialog procedure:
case WM_SIZE:
SendMessageW(GetDlgItem(hWnd, IDC_STATUS_BAR), WM_SIZE, 0, 0);
return FALSE;
and the status bar control will automatically follow its parent's client area.
For the last two questions:
From the fact that your WinMain accepts LPSTR (and not LPWSTR) - I assume that you are NOT building for UNICODE. Then SB_SETTEXT requires an ANSI character string, while you are passing wide string here:
SendMessageW(status, SB_SETTEXT, 0, reinterpret_cast<LPARAM>(L"Test"));
You should either pass a narrow string:
SendMessageW(status, SB_SETTEXT, 0, reinterpret_cast<LPARAM>("Test"));
or use SB_SETTEXTW:
SendMessageW(status, SB_SETTEXTW, 0, reinterpret_cast<LPARAM>(L"Test"));
And for the position of your status bar - you create it at a fixed position within the client window:
HWND status = CreateWindowExW(0, STATUSCLASSNAMEW, nullptr, WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0,
client_rect.bottom - client_rect.top - 20,
client_rect.right - client_rect.left, 20, hWnd, nullptr, hInstance,
nullptr);
When you resize your window - the status bаr stays at the same client coordinates. You should process the WM_SIZE message and move the status bar accordingly.
You should only use dialog-based app if you need only the features provided by the dialog box.
As soon as you start adding status bar, menu bar, accelerators, serialization, etc. - you would be better off using a regular windows app.

WM_CLOSE doesn't work and the application is not resizable

When I attempt to close the dialog, I expect the application to close, but it doesn't. I assume something is wrong with WM_CLOSE.
The application is not resizable. How do I make it so?
Do I really need UpdateWindow(hWnd)?
#include <Windows.h>
#include "resource.h"
#pragma comment(linker, "\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
INT_PTR CALLBACK DialogProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_INITDIALOG:
return TRUE;
case WM_CLOSE:
DestroyWindow(hwnd);
PostQuitMessage(0);
return FALSE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
EndDialog(hwnd, IDOK);
break;
case IDCANCEL:
EndDialog(hwnd, IDCANCEL);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
int WINAPI WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nShowCmd
)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
HWND hWnd = CreateDialogParamW(hInstance, MAKEINTRESOURCEW(IDD_MAIN), nullptr, &DialogProc, 0);
if (!hWnd)
{
MessageBoxW(nullptr, L"Dialog Creation Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hWnd, nShowCmd);
UpdateWindow(hWnd);
MSG msg;
while (GetMessageW(&msg, hWnd, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return msg.wParam;
}
Resource.rc
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_MAIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 302
TOPMARGIN, 7
BOTTOMMARGIN, 169
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_MAIN DIALOGEX 0, 0, 309, 176
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Test"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LISTBOX IDC_LIST2,48,30,235,56,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Static",IDC_STATIC,146,92,48,40
PUSHBUTTON "Button1",IDC_BUTTON1,215,127,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_MAIN AFX_DIALOG_LAYOUT
BEGIN
0
END
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Resource.rc
//
#define IDD_MAIN 103
#define IDC_LIST2 1005
#define IDC_BUTTON1 1006
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 105
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1007
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
The problem is you are passing hWnd as a parameter to GetMessage(). This causes GetMessage() to only retrieve messages for the window. But WM_QUIT is not sent to your window, but to your thread. Since GetMessage() never retrieves the WM_QUIT message, the message loop never exits.
The proper approach is to pass nullptr instead of hWnd.

Effect of MoveWindow over ListView Control: why column headers hides away after calling the function? [duplicate]

This question already has an answer here:
Effect of MoveWindow in EnumChildWindows over listview inside the Dialog Box: Why ListView Header is not correctly scrolling
(1 answer)
Closed 4 years ago.
I have a dialog box with a listview control (lvc) in it. Because there are many editbox before lvc( 57 controls including lvc ), lvc is out of the screen. So i have to make a vertical scroll bar.
Vertical scroll bar:
Range : 0-250
every SB_PAGEDOWN, SB_PAGEUP, SB_LINEDOWN and SB_LINEUP changes scroll position by 25
#define max_scroll_range 250
#define min_scroll_range 0
#define scroll_step max_scroll_range/10
Project file overview
I am providing all the files so that you could see the problem live.
main.cpp
#include "include/basefile01.h"
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
HINSTANCE gi ;
HWND parentHwnd;
/* Make the class name into a global variable */
TCHAR szClassName[ ] = _T("IGAM");
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = gi = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = (HICON)MAKEINTRESOURCE(APP_ICON_XL);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = MAKEINTRESOURCE(MAIN_MENU); /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl.hbrBackground = (HBRUSH) GetStockObject( WHITE_BRUSH );
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
parentHwnd = hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
_T("IGAM"), /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
544, /* The programs width */
375, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow (hwnd, nCmdShow);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_COMMAND:
switch(LOWORD(wParam)){
case MAIN_MENU_file_new_invoice:
DialogBox(gi, MAKEINTRESOURCE(NEW_INVOICE_DIALOG), parentHwnd, (DLGPROC)invoice_dialog_box_message_handle);
break;
}
break;
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
this file calls the DialogBox which connects it with other files.
basefile01.cpp
#include "../include/basefile01.h"
#include <vector>
#define max_scroll_range 250
#define min_scroll_range 0
#define scroll_step max_scroll_range/10
long iPrevVscroll = 0;
BOOL CALLBACK invoice_dialog_box_message_handle(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
static long iVscroll;
switch(msg)
{
case WM_INITDIALOG:
iVscroll = 0;
SetScrollRange(hwnd, SB_VERT, min_scroll_range, max_scroll_range, TRUE);
SetScrollPos(hwnd, SB_VERT, min_scroll_range, TRUE);
create_listViews_invoice_dialog(hwnd);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wp))
{
case IDCANCEL:EndDialog(hwnd, wp); return TRUE;
}
break;
/**
there are two variables #iVscroll and #iPrevVscroll
they are there because the every child window will be moved up
by the between previous scroll position and the current scroll position
*/
case WM_VSCROLL:
switch(LOWORD(wp))
{
case SB_PAGEDOWN:
case SB_LINEDOWN : iVscroll += scroll_step; break;
case SB_PAGEUP:
case SB_LINEUP: iVscroll -= scroll_step; break;
case SB_THUMBTRACK: iVscroll = HIWORD(wp); break;
};
/// iVscroll should be in the range of min_scroll_range and max_scroll_range
iVscroll = ( iVscroll < min_scroll_range ? min_scroll_range : ( iVscroll > max_scroll_range ? max_scroll_range : iVscroll ) );
/// don't move any child windows if iVscroll is at boundaries
if(!iVscroll || iVscroll == iPrevVscroll ) return TRUE;
SetScrollPos(hwnd, SB_VERT, iVscroll, TRUE);
/// Enumerate to all child windows of the dialog box; this is better than calling and moving each window in a loop
EnumChildWindows(hwnd, invoice_dialog_child_enum_scroll, (LPARAM)iVscroll);
iPrevVscroll = iVscroll;
/// redraw the whole dialog box client area
InvalidateRect (hwnd, NULL, TRUE) ;
UpdateWindow(hwnd);
return TRUE;
default :return FALSE;
}
}
BOOL CALLBACK invoice_dialog_child_enum_scroll(HWND hwnd, LPARAM lp)
{
long s = (long) lp;
RECT rc;
GetWindowRect(hwnd, &rc);
/// the above function return the coordinates relative to the top left of the screen at which\
i am looking at. So to convert those coordinates which are relative to\
the dialog box the following function is used
MapWindowPoints(HWND_DESKTOP, GetParent(hwnd), (LPPOINT)&rc, 2);
/// move the window by the difference between #iVscroll and #iPrevVscroll
MoveWindow(hwnd, rc.left, rc.top - ( s - iPrevVscroll ), rc.right-rc.left, rc.bottom - rc.top, TRUE);
//SetWindowPos(hwnd, HWND_TOP,rc.left, rc.top - ( s - iPrevVscroll ), rc.right-rc.left, rc.bottom - rc.top,SWP_NOOWNERZORDER | SWP_NOSIZE);
}
BOOL create_listViews_invoice_dialog(HWND hwnd)
{
/**
this function creates the listview successfully
*/
/// initializing the listview common control
INITCOMMONCONTROLSEX icx;
icx.dwSize = sizeof(INITCOMMONCONTROLSEX);
icx.dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&icx);
RECT LV_rect = {10,25,380,375};
/// changing to the above coordinates to coordinates in dialog units
MapDialogRect(hwnd, &LV_rect);
/// creating the list view control
HWND lv_hwnd = CreateWindow(
WC_LISTVIEW,
L"",
WS_CHILD | LVS_REPORT | LVS_EDITLABELS | WS_VISIBLE,
LV_rect.left, LV_rect.top,
LV_rect.right - LV_rect.left,
LV_rect.bottom - LV_rect.top,
hwnd,
(HMENU)nid_itd_lv,
(HINSTANCE)GetWindowLong(GetParent(hwnd), GWL_HINSTANCE),
NULL
);
/// adding some extended styles and adding columns
ListView_SetExtendedListViewStyle(lv_hwnd, LVS_EX_FLATSB | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP );
create_invoice_lv_columns(lv_hwnd);
}
BOOL create_invoice_lv_columns(HWND hwnd)
{
LVCOLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_WIDTH | LVCF_TEXT;
/// some variables deceleration
int col_fmt[5] = { LVCFMT_CENTER, LVCFMT_LEFT, LVCFMT_CENTER, LVCFMT_CENTER, LVCFMT_CENTER };
int col_wid[5] = { 30, 90, 50, 30, 70 };
std::vector<TCHAR*> col_nam(5);
col_nam[0] = _T("S.No"); col_nam[1] = _T("Description"); col_nam[2] = _T("HSN"); col_nam[3] = _T("QTY"); col_nam[4] = _T("Rate");
for(int i =0; i < 5; i++)
{
lvc.fmt = col_fmt[i];
lvc.cx = col_wid[i];
lvc.pszText = col_nam[i];
lvc.iSubItem = i;
ListView_InsertColumn(hwnd, i, &lvc);
}
}
basefile01.h
#define _UNICODE
#define UNICODE
#include <tchar.h>
#define _WIN32_IE 0x0700
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include "main_rsc.h"
BOOL CALLBACK invoice_dialog_box_message_handle(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK invoice_dialog_child_enum_scroll(HWND, LPARAM);
BOOL create_listViews_invoice_dialog(HWND);
BOOL create_invoice_lv_columns(HWND);
main_res.h
#define MAIN_MENU 1
#define NEW_INVOICE_DIALOG_MENU 2
#define NEW_INVOICE_DIALOG 3
#define NEW_INVOICE_DIALOG_MENU_save 4
#define NEW_INVOICE_DIALOG_MENU_help 6
#define APP_ICON_XL 7
#define APP_ICON_S 8
#define MAIN_MENU_file_new_invoice 102
#define MAIN_MENU_file_new_challan 103
#define MAIN_MENU_file_open 104
#define MAIN_MENU_file_export_jpeg 105
#define MAIN_MENU_file_export_pdf 106
#define nid_ponumber_c 107
#define nid_ponumber_t 108
#define nid_podate_c 109
#define nid_podate_t 110
#define nid_vcode_c 111
#define nid_vcode_t 112
#define nid_inv_no_c 113
#define nid_inv_no_t 114
#define nid_inv_date_t 115
#define nid_inv_date_c 116
#define nid_seller_gstin_c 117
#define nid_seller_gstin_t 118
#define nid_seller_info 119
#define nid_seller_state_c 120
#define nid_seller_state_t 121
#define nid_ship_info 122
#define nid_ship_date_c 123
#define nid_ship_date_t 124
#define nid_ship_add_t 125
#define nid_ship_add_c 126
#define nid_ship_mode_t 127
#define nid_ship_mode_c 128
#define nid_ship_to_t 129
#define nid_ship_to_c 130
#define nid_ship_gstin_t 131
#define nid_ship_gstin_c 132
#define nid_ship_state_t 133
#define nid_ship_state_c 134
#define nid_order_info 135
#define nid_bt_info 136
#define nid_bt_to_t 137
#define nid_bt_to_c 138
#define nid_bt_add_t 139
#define nid_bt_add_c 140
#define nid_bt_gstin_t 141
#define nid_bt_gstin_c 142
#define nid_bt_state_t 143
#define nid_bt_state_c 144
#define nid_is_bt_st_same_ 145
#define nid_tax_info 146
#define nid_tax_rc_t 147
#define nid_tax_rc_c 148
#define nid_tax_cgst_t 149
#define nid_tax_cgst_c 150
#define nid_tax_sgst_t 151
#define nid_tax_sgst_c 152
#define nid_tax_igst_t 153
#define nid_tax_igst_c 154
#define nid_itd_info 155
#define nid_itd_lv 156
#define nid_itd_mat_t 157
#define nid_itd_mat_c 158
#define nid_itd_qty_t 159
#define nid_itd_qty_c 160
#define nid_itd_hsn_t 161
#define nid_itd_hsn_c 162
#define nid_itd_rate_t 163
#define nid_itd_rate_c 164
main_res.rc
#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "../include/main_rsc.h"
///////// MENUS
MAIN_MENU MENU
{
POPUP "File"
{
POPUP "New"
{
MENUITEM "Invoice", MAIN_MENU_file_new_invoice
MENUITEM "Challan", MAIN_MENU_file_new_challan
}
MENUITEM "&open", MAIN_MENU_file_open
POPUP "&Export"
{
MENUITEM "JPEG", MAIN_MENU_file_export_jpeg
MENUITEM "PDF", MAIN_MENU_file_export_pdf
}
}
}
NEW_INVOICE_DIALOG_MENU MENU
{
MENUITEM "&save", NEW_INVOICE_DIALOG_MENU_save
MENUITEM "&help",NEW_INVOICE_DIALOG_MENU_help,HELP
}
//////////////// ICONS
APP_ICON_XL ICON "icons/icon02_256.ico"
APP_ICON_S ICON "icons/icon02_16.ico"
/**
DIALOG resource
*/
NEW_INVOICE_DIALOG DIALOGEX 0,0,500,300
CAPTION "New Invoice"
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU | WS_THICKFRAME | WS_VSCROLL
MENU NEW_INVOICE_DIALOG_MENU
FONT 8, "Ms Shell Dlg"
{
GROUPBOX "Purchase Order Information", nid_order_info, 10, 10, 370, 65
LTEXT "PO NUMBER",nid_ponumber_t, 20, 20, 50, 12
EDITTEXT nid_ponumber_c, 70, 20, 100, 12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
LTEXT "PO DATE", nid_podate_t, 20, 40, 50, 12
EDITTEXT nid_podate_c, 70, 40, 100, 12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
LTEXT "Vendor Code", nid_vcode_t, 20, 60, 50, 12
EDITTEXT nid_vcode_c, 70, 60, 100, 12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
GROUPBOX "Seller Information", nid_seller_info, 10,80, 180, 70
LTEXT "Invoice No.", nid_inv_no_t, 20, 90, 50, 20
EDITTEXT nid_inv_no_c, 70, 90, 100, 12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
LTEXT "Invoice date", nid_inv_date_t, 20, 110, 50, 12
EDITTEXT nid_inv_date_c, 70, 110, 100, 12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
LTEXT "GSTIN", nid_seller_gstin_t, 20, 130, 50, 12
EDITTEXT nid_seller_gstin_c, 70, 130, 100, 12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
GROUPBOX "Billed To", nid_bt_info, 10, 155, 180, 100
LTEXT "Name", nid_bt_to_t, 20,170,50,12
EDITTEXT nid_bt_to_c, 70, 170,100,12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
LTEXT "Address", nid_bt_add_t, 20,190,50,12
EDITTEXT nid_bt_add_c, 70,190,100,12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
LTEXT "GSTIN", nid_bt_gstin_t, 20, 210, 50,12
EDITTEXT nid_bt_gstin_c, 70,210,100,12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
LTEXT "State", nid_bt_state_t, 20, 230,50,12
EDITTEXT nid_bt_state_c, 70,230,100,12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
CHECKBOX "Shipped to is same as Billed to", nid_is_bt_st_same_, 200, 230, 180,20
GROUPBOX "Shipping Information", nid_ship_info, 200, 80, 180, 140
LTEXT "Name ", nid_ship_to_t, 210, 100, 50, 12
EDITTEXT nid_ship_to_c, 260, 100, 100, 12,ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
LTEXT "Address", nid_ship_add_t , 210, 120, 50,12
EDITTEXT nid_ship_add_c, 260, 120,100,10, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
LTEXT "GSTIN", nid_ship_gstin_t, 210,140,50,12
EDITTEXT nid_ship_gstin_c, 260,140,100,12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
LTEXT "Date", nid_ship_date_t, 210,160,50,12
EDITTEXT nid_ship_date_c, 260,160,100,12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
LTEXT "Mode", nid_ship_mode_t, 210, 180,50,12
EDITTEXT nid_ship_mode_c, 260, 180,100,12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
LTEXT "State", nid_ship_state_t, 210,200,50,12
EDITTEXT nid_ship_state_c, 260,200,100,12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_AUTOHSCROLL
GROUPBOX "Taxing information", nid_tax_info, 10,270,370, 45
CTEXT "CGST (%)", nid_tax_cgst_t, 25, 280, 100, 12
EDITTEXT nid_tax_cgst_c, 25,295, 100, 12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_NUMBER
CTEXT "SGST (%)", nid_tax_sgst_t, 135, 280, 100, 12
EDITTEXT nid_tax_sgst_c, 135,295, 100, 12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_NUMBER
CTEXT "IGST (%)", nid_tax_igst_t, 255, 280, 100, 12
EDITTEXT nid_tax_igst_c, 255,295, 100, 12, ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP | ES_NUMBER
}
by the way I am using codes bock on windows vista home basics SPS2 (32 bit)
Problem
Problem is with the MoveWindow function inside invoice_dialog_child_enum_scroll function in basefile01.cpp.
whenever WM_VSCROLL is processed and the lvc is moved up and all of its column header vanishes.
however there is no mistake or error ( as fas as I know ) in making lisview and its columns because when i change the coordinates of the lvc, so that when it is created it is on the screen which is visible to me at that time, and the moment when I click the line down/up, page down/up and thumbtrack, those column headers vanishes.
and also that if you compare the size of the lvc in both the images, first one is undesirably too small.
as mush as i could debug this project, it is MoveWindow which is making this problem and SetWindowPos is no better.
I know that this post is very long but any of your suggestion would be great!
Thanks for your time.
EnumChildWindows will go through all child windows including descendants. Meanwhile, ListView control has a child header control, that header control ends up being moved in enum procedure. You should instead move the listview control only. You can use a for loop to go through the child windows, not the descendants:
for(HWND child = GetWindow(hwnd, GW_CHILD); child;
child = GetWindow(child, GW_HWNDNEXT)) { }
...
Also use SetScrollInfo to more accurately set the scroller bar information. Example:
std::map<HWND, int> item_positions;
BOOL CALLBACK diaproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM)
{
static HWND hlist;
switch(msg)
{
case WM_INITDIALOG:
{
hlist = CreateWindow(WC_LISTVIEW, NULL, WS_CHILD | WS_VISIBLE | LVS_REPORT,
10, 100, 300, 2000, hwnd, NULL, NULL, NULL);
ListView_SetExtendedListViewStyle(hlist, LVS_EX_GRIDLINES);
std::vector<TCHAR*> col_names = { TEXT("text1"), TEXT("text2") };
LVCOLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_WIDTH | LVCF_TEXT;
for(int i = 0; i < (int)col_names.size(); i++)
{
lvc.fmt = LVCFMT_LEFT;
lvc.cx = 100;
lvc.pszText = col_names[i];
lvc.iSubItem = i;
ListView_InsertColumn(hlist, i, &lvc);
}
RECT rc;
GetClientRect(hwnd, &rc);
//find the lowest point in dialog:
RECT list_rect;
GetClientRect(hlist, &list_rect);
POINT pt = { list_rect.right, list_rect.bottom };
ScreenToClient(hwnd, &pt);
SCROLLINFO info = { sizeof(SCROLLINFO) };
info.fMask = SIF_ALL;
info.nMin = 0;
info.nMax = pt.y + rc.bottom - 1;
info.nPage = rc.bottom;
info.fMask = SIF_ALL;
SetScrollInfo(hwnd, SB_VERT, &info, TRUE);
//save y-positions for later
for(HWND child = GetWindow(hwnd, GW_CHILD); child;
child = GetWindow(child, GW_HWNDNEXT))
{
GetWindowRect(child, &rc);
pt = { rc.left, rc.top };
ScreenToClient(hwnd, &pt);
item_positions[child] = pt.y;
}
return FALSE;
}
case WM_VSCROLL:
{
SCROLLINFO info = { sizeof(info) };
info.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_VERT, &info);
int pos = info.nPos;
int track = HIWORD(wParam);
switch(LOWORD(wParam))
{
case SB_LEFT: pos = info.nMin; break;
case SB_RIGHT: pos = info.nMax; break;
case SB_LINELEFT: pos--; break;
case SB_LINERIGHT: pos++; break;
case SB_PAGELEFT: pos -= info.nPage; break;
case SB_PAGERIGHT: pos += info.nPage; break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK: pos = track; break;
}
SetScrollPos(hwnd, SB_VERT, pos, FALSE);
int count = 0;
for(HWND child = GetWindow(hwnd, GW_CHILD); child;
child = GetWindow(child, GW_HWNDNEXT))
count++;
HDWP hdwp = BeginDeferWindowPos(count);
for(HWND child = GetWindow(hwnd, GW_CHILD); child;
child = GetWindow(child, GW_HWNDNEXT))
{
RECT rc;
GetWindowRect(child, &rc);
POINT pt = { rc.left, rc.top };
ScreenToClient(hwnd, &pt);
if(item_positions.find(child) != item_positions.end())
{
int y = pos - item_positions[child];
DeferWindowPos(hdwp, child, NULL, pt.x, -y, 0, 0,
SWP_NOSIZE | SWP_NOACTIVATE);
}
}
EndDeferWindowPos(hdwp);
return TRUE;
}
case WM_COMMAND:
if(LOWORD(wParam) == IDCANCEL)
EndDialog(hwnd, wParam);
return TRUE;
default: return FALSE;
}
}
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, int)
{
DialogBox(hinst, MAKEINTRESOURCE(IDD_DIALOG1), 0, (DLGPROC)diaproc);
return 0;
}
As suggested by #Barmak Shemirani and #Paul Sanders, I made whole new project but this time without extra controls and only with listview.
And i have found out that the problem was with the MoveWindow inside EnumChildWindow but I don't know why?
But Check the following link you know know why and also, i have posted the code of that project.
Effect of MoveWindow in EnumChildWindows over listview inside the Dialog Box: Why ListView Header is not correctly scrolling

Tooltip Coloring doesnot work

I am newbie in c++ win32 Programming and I am using visual studio 2013 on Windows 7 X64 SP1.
I have used this code in link below to create tooltip for a button in DialogBox and successfully it worked.
Tooltip for button
but when I want to change the background color or foreground color , it does not work and it shows the default colors.
SendMessage(hwndTip, TTM_SETTIPBKCOLOR, 0xFF326FD8, 0);
//SendMessage(hwndTip, TTM_SETTIPBKCOLOR, (WPARAM)CreateSolidBrush(RGB(255,255, 255), 0);
SendMessage(hwndTip, TTM_SETTIPTEXTCOLOR, (WPARAM)CreateSolidBrush(RGB(255,255, 255)), 0);
Because in this link :
http://msdn.microsoft.com/en-us/library/windows/desktop/bb760411%28v=vs.85%29.aspx
the MSDN said that "When visual styles are enabled, this message has no effect." so I changed the
HWND hwndTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL,
WS_POPUP | TTS_ALWAYSTIP | TTS_BALLOON |TTS_USEVISUALSTYLE,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
hDlg, NULL,
hInst, NULL);
to :
HWND hwndTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL,
WS_POPUP | TTS_ALWAYSTIP | TTS_BALLOON,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
hDlg, NULL,
hInst, NULL);
but without any success.
also I have used :
#pragma comment(linker, \
"\"/manifestdependency:type='Win32' "\
"name='Microsoft.Windows.Common-Controls' "\
"version='6.0.0.0' "\
"processorArchitecture='*' "\
"publicKeyToken='6595b64144ccf1df' "\
"language='*'\"")
in my code so I removed it to see if tooltip coloring works but the tooltip did not appeared at all !
what is the problem ?
Thanks.
Update 1 :
Here is my full source code , hope to solve the problem :
Main.cpp :
#include <Windows.h>
#include <stdlib.h>
#include <tchar.h>
#include <memory>
#include <malloc.h>
#include "resource.h"
#include <CommCtrl.h>
#include <Uxtheme.h>
HINSTANCE hInst;
BOOL InitInstance(HINSTANCE, int);
INT_PTR CALLBACK MainWin(HWND, UINT, WPARAM, LPARAM);
#pragma comment(linker, \
"\"/manifestdependency:type='Win32' "\
"name='Microsoft.Windows.Common-Controls' "\
"version='6.0.0.0' "\
"processorArchitecture='*' "\
"publicKeyToken='6595b64144ccf1df' "\
"language='*'\"")
#pragma comment(lib, "ComCtl32.lib")
#pragma comment(lib,"UxTheme.lib")
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPTSTR lpCmdLine,_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
MSG msg;
if (!InitInstance(hInstance, nCmdShow))
{
return FALSE;
}
while (GetMessage(&msg, NULL, 0, 0)>0)
{
if (!IsDialogMessage(msg.hwnd,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
}
HWND CreateToolTip(int toolID, HWND hDlg, HINSTANCE hInst, PTSTR pszText)
{
if (!toolID || !hDlg || !pszText)
{
return NULL;
}
HWND hwndTool = GetDlgItem(hDlg, toolID);
if (!hwndTool)
{
return NULL;
}
HWND hwndTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL,
WS_POPUP | TTS_ALWAYSTIP | TTS_BALLOON |TTS_USEVISUALSTYLE,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
hDlg, NULL,
hInst, NULL);
if (!hwndTip)
{
return NULL;
}
TOOLINFO toolInfo = { 0 };
toolInfo.cbSize = sizeof(toolInfo);
toolInfo.hwnd = hDlg;
toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
toolInfo.uId = (UINT_PTR)hwndTool;
toolInfo.lpszText = pszText;
if (!SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo))
{
DestroyWindow(hwndTip);
return NULL;
}
SendMessage(hwndTip, TTM_SETTIPBKCOLOR, 0xFF326FD8, 0);
return hwndTip;
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hWnd = CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_MainDlg), NULL, MainWin, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
SetWindowTheme(hWnd, L"", L"");
return TRUE;
}
INT_PTR CALLBACK MainWin(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
{
CreateToolTip(IDC_TestBtn, hDlg, hInst, L"TESTTOOLTIP");
return (INT_PTR)TRUE;
}
break;
case WM_CLOSE:
DestroyWindow(hDlg);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_COMMAND:
if (LOWORD(wParam) == IDC_TestBtn)
{
MessageBox(NULL, L"TEST", L"TEST", MB_OK);
return (INT_PTR)TRUE;
}
}
return (INT_PTR)FALSE;
}
resource.h :
#define IDD_MainDlg 103
#define IDC_TestBtn 104
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 106
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1006
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
resource script for resource.rc :
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_MainDlg, DIALOG
BEGIN
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_MainDlg DIALOGEX 0, 0, 149, 75
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_TOOLWINDOW
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "testbtn",IDC_TestBtn,41,12,57,49
END
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////

C++: Getting information from a Listbox with LB_GETCURSEL and LB_GETTEXT

I'm creating a Listbox with a list of foders. I want to show the name of the folder the user double click. To do so, I have written:
...
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
char Temp[_MAX_DIR]
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Analizar las selecciones de menú:
switch (wmId)
{
case ID_LIST:
SelIndex = SendMessage(hList, LB_GETCURSEL, 0, 0L);
SendMessage(hList, LB_GETTEXT, (WPARAM)(int)(SelIndex), (LPARAM)(LPCTSTR)(Temp));
printf("The folder is: %s\n", Temp);
...
The most relevant lines are:
SelIndex = SendMessage(hList, LB_GETCURSEL, 0, 0L);
SendMessage(hList, LB_GETTEXT, (WPARAM)(int)(SelIndex), (LPARAM)(LPCTSTR)(Temp));
With the first one I should get the line of the list box the user have clicked, and with the second one I should store into Temp the text that appears in the clicked line. But I get nothing, what am I doing wrong??
Thank you
/////////////////Combining the answers of some users, a script that works is like follows:
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Analizar las selecciones de menú:
if (wmEvent == LBN_DBLCLK)
{
if(wmId == ID_LIST)
{
SelIndex = SendMessage(hList, LB_GETCURSEL, 0, 0L);
printf("The index is %d\n", SelIndex);
len = SendMessage(hList, LB_GETTEXT, (WPARAM)(int)(SelIndex), (LPARAM)(LPCTSTR)(Temp));
printf("Lenght is %d\n", len);
printf("The folder is: %s\n",Temp);
Your program has some problems. First of all you seem to be doing a lot more casting than you need to. That's always a worry. You also neglect basic error checking. For instance:
SelIndex = SendMessage(hList, LB_GETCURSEL, 0, 0L);
You assign to SelIndex but don't check for errors. The documentation tells you that in the event of error, LB_ERR is returned. You must check for that.
Next up is:
SendMessage(hList, LB_GETTEXT, (WPARAM)(int)(SelIndex), (LPARAM)(LPCTSTR)(Temp));
The casting seems extreme. You could write it like this:
SendMessage(hList, LB_GETTEXT, SelIndex, (LPARAM)Temp);
You should also capture the return value and check for errors. Again, you must consult the documentation carefully.
Now, the most likely cause of problems is that you are compiling a Unicode project. And so are expected to supply a buffer of wide characters. So change the declaration of Temp like so:
wchar_t Temp[_MAX_DIR];
Another possible problem is that you are expected to supply a buffer of sufficient length for the string, and the null-terminator. Again, the documentation makes this clear. Use LB_GETTEXTLEN to find out how large a buffer you need.
Note: I was assuming that your code does actually execute. But the other answers suggest that your code may not execute. In which case that's the first thing to sort out. Confirming facts like that is a basic part of debugging and is something that you must learn to do. So, irrespective of what fixes the problem, the best advice I can give you is to try learn how to diagnose and describe a problem better. Doing that makes it much easier for you to narrow the problem down and so find the solution. In other words here, the main problem you had, in my view, was that you had not fully identified your problem.
A couple of more points in addition to what #DavidHeffernan mentioned in his answer:
a) the logic for case ID_LIST should be within if (wmEvent == LBN_DBLCLK)
b) printf() will not do anything in a windows application, try OutputDebugString() instead for debug builds or a MessageBox()
I'm creating a Listbox with a list of foders.I want to show the name of the folder the user double click.
You can use simple list box to do that, or you can use DlgDirList function to do that-all you need to do is to pass DDL_DIRECTORY as the last parameter. This function always adds file names as well to the list box, so you will need to find a way to filter them on your own. Also, notice that it provides HWND of the static control that will display the name of the folder, so this might be useful to you ( this parameter can be NULL if you do not wish to use static control ).
NOTE ABOUT DlgDirList:
Directory names have square brackets like this : [directory].
But I get nothing, what am I doing wrong??
You get some result. You can not just appear here and say "I get nothing". Explain what is the behavior you get, and what is the one you expected.
THE SOLUTION:
After looking at your code, I can see what could be wrong-you haven't handled the LBN_DBLCLK notification message.
Also. note that your list box has to have LBS_NOTIFY style in order to send notification messages to your parent window.
If you provide more detailed explanation of the problem community will have better chance to help you. So far this is the only relevant problem I see in your code.
RESOURCES ( these should help you to solve your problem ):
Microsoft has two good examples for populating list boxes and extracting data from them.
If you are OK with allowing the user to see both files and directories then you can use this example, just do not forget the DDL_DIRECTORY flag I mentioned above.
If you only want directories in your list box than you will find this example useful.
EXAMPLE:
To help you with those examples, I have made a demo application that demonstrates both ways.
This code shows you how to populate list box with your data and how to extract strings on double clicks.
Just go to File and choose one of two options to see the demonstration.
First option in the menu lists the data of the player when you double click the item in the edit control ( I have modified Microsoft's second example from above ), while the second option lists files in your current directory and deletes the file you double click on.
In my opinion, the solution you seek is best illustrated in the dialog procedure ListBoxExampleProc. Pay attention how the items are added ( WM_INITDIALOG handler ) and how I get the string from items on double click ( in WM_COMMAND handler find and study case IDC_LIST1 ).
You will need to implement your desired behavior on your own ( obtaining the directory names and populating the list box properly ) since I had no time to do that for you-Christnmas has passed so no gifts for you this time :)
Hopefully this will help you. If you have further questions leave a comment and I will respond.
Best regards.
INSTRUCTIONS:
Create default Win32 project in Visual Studio. Name it "list box test".
Then all you have to do is to replace the original text of the following files with my code:
stdafx.h:
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
#include <tchar.h>
#include <Strsafe.h>
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here
Resource.h:
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by list box test.rc
//
#define IDC_MYICON 2
#define IDD_LISTBOXTEST_DIALOG 102
#define IDS_APP_TITLE 103
#define IDD_ABOUTBOX 103
#define IDM_ABOUT 104
#define IDM_EXIT 105
#define IDI_LISTBOXTEST 107
#define IDI_SMALL 108
#define IDC_LISTBOXTEST 109
#define IDR_MAINFRAME 128
#define IDD_DIALOG1 129
#define IDD_DIALOG2 130
#define IDC_LIST1 1000
#define IDC_EDIT1 1002
#define IDS_PATHTOFILL 1003
#define ID_FILE_SIMPLELISTBOX 32771
#define ID_FILE_DIRECTORYLISTBOX 32772
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 131
#define _APS_NEXT_COMMAND_VALUE 32773
#define _APS_NEXT_CONTROL_VALUE 1004
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif
list box test.rc:
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#ifndef APSTUDIO_INVOKED
#include "targetver.h"
#endif
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_LISTBOXTEST ICON "list box test.ico"
IDI_SMALL ICON "small.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDC_LISTBOXTEST MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "Simple list box", ID_FILE_SIMPLELISTBOX
MENUITEM "Directory list box", ID_FILE_DIRECTORYLISTBOX
MENUITEM "E&xit", IDM_EXIT
END
POPUP "&Help"
BEGIN
MENUITEM "&About ...", IDM_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDC_LISTBOXTEST ACCELERATORS
BEGIN
"?", IDM_ABOUT, ASCII, ALT
"/", IDM_ABOUT, ASCII, ALT
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About list box test"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
ICON 128,IDC_STATIC,14,14,21,20
LTEXT "list box test, Version 1.0",IDC_STATIC,42,14,114,8,SS_NOPREFIX
LTEXT "Copyright (C) 2014",IDC_STATIC,42,26,114,8
DEFPUSHBUTTON "OK",IDOK,113,41,50,14,WS_GROUP
END
IDD_DIALOG1 DIALOGEX 0, 0, 335, 180
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,205,159,50,14
PUSHBUTTON "Cancel",IDCANCEL,278,159,50,14
LISTBOX IDC_LIST1,23,14,99,140,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_EDIT1,140,34,179,22,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY
END
IDD_DIALOG2 DIALOGEX 0, 0, 316, 180
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,205,159,50,14
PUSHBUTTON "Cancel",IDCANCEL,259,159,50,14
LISTBOX IDC_LIST1,24,17,173,141,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
LTEXT "",IDS_PATHTOFILL,209,31,90,18,0,WS_EX_CLIENTEDGE
CTEXT "Current working directory:",IDC_STATIC,209,18,89,9,SS_ENDELLIPSIS
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_ABOUTBOX, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 163
TOPMARGIN, 7
BOTTOMMARGIN, 55
END
IDD_DIALOG1, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 328
TOPMARGIN, 7
BOTTOMMARGIN, 173
END
IDD_DIALOG2, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 309
TOPMARGIN, 7
BOTTOMMARGIN, 173
END
END
#endif // APSTUDIO_INVOKED
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#ifndef APSTUDIO_INVOKED\r\n"
"#include ""targetver.h""\r\n"
"#endif\r\n"
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_APP_TITLE "list box test"
IDC_LISTBOXTEST "LISTBOXTEST"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
list box test.cpp:
// list box test.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "list box test.h"
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
//*********** Variables required for the second list box example
typedef struct
{
TCHAR achName[MAX_PATH];
TCHAR achPosition[12];
int nGamesPlayed;
int nGoalsScored;
} Player;
Player Roster[] =
{
{TEXT("Haas, Jonathan"), TEXT("Midfield"), 18, 4 },
{TEXT("Pai, Jyothi"), TEXT("Forward"), 36, 12 },
{TEXT("Hanif, Kerim"), TEXT("Back"), 26, 0 },
{TEXT("Anderberg, Michael"), TEXT("Back"), 24, 2 },
{TEXT("Jelitto, Jacek"), TEXT("Midfield"), 26, 3 },
{TEXT("Raposo, Rui"), TEXT("Back"), 24, 3},
{TEXT("Joseph, Brad"), TEXT("Forward"), 13, 3 },
{TEXT("Bouchard, Thomas"), TEXT("Forward"), 28, 5 },
{TEXT("Salmre, Ivo "), TEXT("Midfield"), 27, 7 },
{TEXT("Camp, David"), TEXT("Midfield"), 22, 3 },
{TEXT("Kohl, Franz"), TEXT("Goalkeeper"), 17, 0 },
};
//**************************************************
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_LISTBOXTEST, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_LISTBOXTEST));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage are only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_LISTBOXTEST));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_LISTBOXTEST);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//************ Modified second example of the list box *****************//
//*********** from http://msdn.microsoft.com/en-us/library/windows/desktop/hh298365%28v=vs.85%29.aspx
INT_PTR CALLBACK ListBoxExampleProc(HWND hDlg, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
// Add items to list.
HWND hwndList = GetDlgItem(hDlg, IDC_LIST1);
for (int i = 0; i < ARRAYSIZE(Roster); i++)
{
int pos = (int)SendMessage(hwndList, LB_ADDSTRING, 0,
(LPARAM) Roster[i].achName);
// we do not need the rest from Microsoft's example
}
// Set input focus to the list box.
SetFocus(hwndList);
return TRUE;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
case IDCANCEL:
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
case IDC_LIST1:
{
switch (HIWORD(wParam))
{
case LBN_DBLCLK:
{
HWND hwndList = GetDlgItem(hDlg, IDC_LIST1);
// Get selected index.
int lbItem = (int)SendMessage(hwndList, LB_GETCURSEL, 0, 0);
// display item's text
TCHAR buff[MAX_PATH];
SendMessage(hwndList, LB_GETTEXT, lbItem, (LPARAM)buff);
SetDlgItemText(hDlg, IDC_EDIT1, buff);
return TRUE;
}
}
}
return TRUE;
}
}
return FALSE;
}
//************ Modified first example of the list box **************//
//*********** from http://msdn.microsoft.com/en-us/library/windows/desktop/hh298372%28v=vs.85%29.aspx
INT_PTR CALLBACK DlgDelFileProc(HWND hDlg, UINT message,
UINT wParam, LONG lParam)
{
PTSTR pszCurDir;
PTSTR pszFileToDelete;
int iLBItem;
int cStringsRemaining;
int iRet;
TCHAR achBuffer[MAX_PATH];
TCHAR achTemp[MAX_PATH];
BOOL fResult;
switch (message)
{
case WM_INITDIALOG:
// Initialize the list box by filling it with files from
// the current directory.
pszCurDir = achBuffer;
GetCurrentDirectory(MAX_PATH, pszCurDir);
DlgDirList(hDlg, pszCurDir, IDC_LIST1, IDS_PATHTOFILL, DDL_DIRECTORY);
SetFocus(GetDlgItem(hDlg, IDC_LIST1));
return FALSE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_LIST1:
if( HIWORD(wParam) == LBN_DBLCLK )
{
// When the user double clicks the item,
// first retrieve the selected file.
pszFileToDelete = achBuffer;
DlgDirSelectEx(hDlg, pszFileToDelete, MAX_PATH, IDC_LIST1);
// Make sure the user really wants to delete the file.
achTemp[MAX_PATH];
StringCbPrintf (achTemp, ARRAYSIZE(achTemp),
TEXT("Are you sure you want to delete %s?"),
pszFileToDelete);
iRet = MessageBox(hDlg, achTemp, L"Deleting Files",
MB_YESNO | MB_ICONEXCLAMATION);
if (iRet == IDNO)
return TRUE;
// Delete the file.
fResult = DeleteFile(pszFileToDelete);
if (!fResult)
{
MessageBox(hDlg, L"Could not delete file.", NULL, MB_OK);
}
else // Remove the filename from the list box.
{
// Get the selected item.
iLBItem = SendMessage(GetDlgItem(hDlg, IDC_LIST1),
LB_GETCURSEL, 0, 0);
// Delete the selected item.
cStringsRemaining = SendMessage(GetDlgItem(hDlg, IDC_LIST1),
LB_DELETESTRING, iLBItem, 0);
// If this is not the last item, set the selection to
// the item immediately following the one just deleted.
// Otherwise, set the selection to the last item.
if (cStringsRemaining > iLBItem)
{
SendMessage(GetDlgItem(hDlg, IDC_LIST1), LB_SETCURSEL,
iLBItem, 0);
}
else
{
SendMessage(GetDlgItem(hDlg, IDC_LIST1), LB_SETCURSEL,
cStringsRemaining, 0);
}
}
}
break;
case IDOK:
case IDCANCEL:
// Destroy the dialog box.
EndDialog(hDlg, TRUE);
return TRUE;
default:
return FALSE;
}
default:
return FALSE;
}
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case ID_FILE_SIMPLELISTBOX:
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, ListBoxExampleProc);
break;
case ID_FILE_DIRECTORYLISTBOX:
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG2), hWnd, DlgDelFileProc);
break;
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
Actually what I get is first letter of selected listbox element.
//hEdit 2 - edit widnow, hWndList - listbox window
char z[20] = {"hhhhh"};
LRESULT SelIndex;
SelIndex = SendMessage(hWndList, LB_GETCURSEL, 0, 0L);
tmp_str = std::to_string(SelIndex);
SendMessage(hWndList, LB_GETTEXT, SelIndex, (LPARAM)z);
SetWindowTextA(hEdit2, z);