Can't disable window (radio buttons) in my tab WIN32 API - c++

I want to disable the radio buttons when I select the checkbox. It works when I pass hwnd in addFunc2(), however, I need it to be in the second tab but somehow I can't find any way to make it work.
I apologize if its confusing, I'm very new at this, and my first time posting here. Please let me know if I need to clarify it more. Please refer to the images and some of my code below:
Result of code:
What I need:
HWND hRadio1, hRadio2, hTab, g_tabPanes[2];
HWND CreateTabPane(HWND tabctrl, int id, HINSTANCE instance)
{
RECT rcTab;
GetClientRect(tabctrl, &rcTab);
TabCtrl_AdjustRect(tabctrl, FALSE, &rcTab);
int wd = rcTab.right - rcTab.left;
int hgt = rcTab.bottom - rcTab.top;
return CreateWindow(
L"static", L"",
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
rcTab.left, rcTab.top, wd, hgt,
tabctrl,
(HMENU)id,
instance,
NULL
);
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
{
addControl(hwnd);
HINSTANCE hInst = GetModuleHandle(NULL);
RECT rc; int dx, dy;
GetClientRect(hwnd, &rc);
dx = rc.right - rc.left;
dy = rc.bottom - rc.top;
TCITEM tie = {
TCIF_TEXT | TCIF_IMAGE,
0, 0,
NULL,
0, -1, 0
};
hTab = CreateWindowEx(NULL, WC_TABCONTROL, _T(""),
WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
0, 0, dx, dy, hwnd,
(HMENU)1001, hInst, NULL
);
tie.pszText = (LPWSTR)_T("Tab 1");
TabCtrl_InsertItem(hTab, 0, &tie);
tie.pszText = (LPWSTR)_T("Tab 2");
TabCtrl_InsertItem(hTab, 1, &tie);
for (int i = 0; i < 2; i++)
g_tabPanes[i] = CreateTabPane(hTab, TAB_ID + i, hInst);
addFunc1(g_tabPanes[0]);
addFunc2(g_tabPanes[1]);
break;
}
case WM_COMMAND:
{
switch (wParam)
{
case ID_CHECKBOX:
{
switch (HIWORD(wParam))
{
case BN_CLICKED:
if (SendDlgItemMessage(hwnd, ID_CHECKBOX, BM_GETCHECK, 0, 0))
{
EnableWindow(hRadio1, true);
EnableWindow(hRadio2, true);
}
else
{
EnableWindow(hRadio1, false);
EnableWindow(hRadio2, false);
}
break;
}
}
break;
case WM_NOTIFY:
{
LPNMHDR ns = (LPNMHDR)lParam;
if ((ns->idFrom == 1001) && (ns->code == TCN_SELCHANGE))
{
int pane = TabCtrl_GetCurSel(hTab);
for (int i = 0; i < 2; i++)
if (pane == i)
ShowWindow(g_tabPanes[i], SW_SHOW);
else
ShowWindow(g_tabPanes[i], SW_HIDE);
}
}
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
void addFunc2(HWND hwnd)
{
HWND hCheckbox;
CreateWindow(TEXT("static"), TEXT("Duplex: "), WS_CHILD | WS_VISIBLE,
75, 10, 90, 25, hwnd, NULL, NULL, NULL);
hCheckbox = CreateWindow(L"button", L"Print on both sides", WS_CHILD | WS_VISIBLE |
BS_AUTOCHECKBOX | WS_TABSTOP,
75, 30, 150, 30, hwnd, (HMENU)ID_CHECKBOX, g_hinst, NULL);
hRadio1 = CreateWindow(L"button", L"Flip on long edge", WS_CHILD | WS_VISIBLE |
BS_AUTORADIOBUTTON | WS_TABSTOP,
75, 55, 150, 30, hwnd, (HMENU)ID_RADIO1, g_hinst, NULL);
hRadio2 = CreateWindow(L"button", L"Flip on short edge", WS_CHILD | WS_VISIBLE |
BS_AUTORADIOBUTTON | WS_TABSTOP,
75, 80, 150, 30, hwnd, (HMENU)ID_RADIO2, g_hinst, NULL);
SendMessage(hCheckbox, BM_SETCHECK, BST_CHECKED, 0);
SendMessage(hRadio1, BM_SETCHECK, BST_CHECKED, 0);

Related

C++ Jump to case label error while doing windows.h

I was programming C++ and came across an error that said "Jump to case label" that i could not fix.I searched the internet and found no solution that worked. How do i fix this error?
#include<iostream>
#include<windows.h>
using namespace std;
LRESULT CALLBACK WindowProcessMessages(HWND hwnd, UINT msg, WPARAM param, LPARAM lparam);
INT WINAPI WinMain(HINSTANCE currentInstance, HINSTANCE previousInstance, PSTR cmdLine, INT cmdCount){
const char *CLASS_NAME = "myWin32WindowClass";
WNDCLASS wc{};
wc.hInstance = currentInstance;
wc.lpszClassName = CLASS_NAME;
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpfnWndProc = WindowProcessMessages;
RegisterClass(&wc);
CreateWindow(CLASS_NAME, "Operating System", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, nullptr, nullptr, nullptr, nullptr);
MSG msg{};
while(GetMessage(&msg, nullptr, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
#define ID_BUTTON 1
#define ID_BUTTON2 2
#define TEXTBOX 3
#define FILE_MENU_NEW 4
#define FILE_MENU_OPEN 5
#define FILE_MENU_EXIT 6 //<-"Jump to case label" error is right here
static HWND hwndTextbox;
LRESULT CALLBACK WindowProcessMessages(HWND hwnd, UINT msg, WPARAM param, LPARAM lparam){
switch(msg){
case WM_CREATE:{
CreateWindow(TEXT("STATIC"), TEXT("value"), WS_VISIBLE | WS_CHILD, 10, 10, 100, 25, hwnd, (HMENU) NULL, NULL, NULL);
CreateWindow(TEXT("BUTTON"), TEXT("testButton"), WS_CHILD | WS_VISIBLE, 10, 30, 80, 20, hwnd, (HMENU) ID_BUTTON, NULL, NULL);
CreateWindow(TEXT("EDIT"), TEXT("VALUE"), WS_VISIBLE | WS_CHILD | WS_BORDER, 10, 70, 200, 20, hwnd, (HMENU) NULL, NULL, NULL );
CreateWindow(TEXT("BUTTON"), TEXT("Title change"), WS_CHILD | WS_VISIBLE, 10, 130, 80, 20, hwnd, (HMENU) ID_BUTTON2, NULL, NULL);
hwndTextbox = CreateWindow(TEXT("EDIT"), TEXT("Change To What?"), WS_VISIBLE | WS_CHILD | WS_BORDER, 10, 100, 200, 20, hwnd, (HMENU) TEXTBOX, NULL, NULL );
HMENU hMenubar = CreateMenu();
HMENU hFile = CreateMenu();
HMENU hOptions = CreateMenu();
HMENU hSubmenu = CreateMenu();
AppendMenu(hSubmenu, MF_POPUP, NULL, "SubMenu Item");
AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hFile, "File");
AppendMenu(hMenubar, MF_POPUP, NULL, "Edit");
AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hOptions, "Options");
AppendMenu(hFile, MF_STRING, FILE_MENU_EXIT, "Exit");
AppendMenu(hFile, MF_POPUP, (UINT_PTR)hSubmenu, "Open Submenu");
AppendMenu(hOptions, MF_STRING, NULL, "Option 1");
AppendMenu(hOptions, MF_SEPARATOR, NULL, NULL);
AppendMenu(hOptions, MF_STRING, NULL, "Option 2");
SetMenu(hwnd, hMenubar);
break;
}
case WM_COMMAND:{
switch(LOWORD(param)){
case ID_BUTTON:
MessageBox(hwnd, "button has been clicked", "title for popup", MB_ICONINFORMATION);
break;
case ID_BUTTON2:
int len = GetWindowTextLength(hwndTextbox) + 1;
static char title[500];
GetWindowText(hwndTextbox, title, len);
SetWindowText(hwnd, title);
case FILE_MENU_EXIT:
DestroyWindow(hwnd);
break;
case
}
break;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, msg, param, lparam);
}
}
Here, you are creating variables that exist in the same scope as other cases, but whose initialization is skipped by those cases.
That's what the error is telling you.
case ID_BUTTON2:
int len = GetWindowTextLength(hwndTextbox) + 1;
static char title[500];
GetWindowText(hwndTextbox, title, len);
SetWindowText(hwnd, title);
You can fix it by limiting the scope of these variables.
case ID_BUTTON2:
{
int len = GetWindowTextLength(hwndTextbox) + 1;
static char title[500];
GetWindowText(hwndTextbox, title, len);
SetWindowText(hwnd, title);
}
You may have also overlooked a break; for that case.

Change button colors

I want to change button colors when the user click on it.
The main plan is: every month 10th one worker's button go to red and if the worker done his job then click on the button and it going to be green.
I have no idea what to do.
I already have this code. I just created a window and add a button to it:
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CREATE:
AddButton(hWnd);
break;
default:
return DefWindowProcW(hWnd, msg, wp, lp);
}
}
void AddButton(HWND hWnd)
{
CreateWindowW(L"Button", L"Change colors", WS_VISIBLE | WS_CHILD,
350, 200,
100, 100,
hWnd,
NULL,
NULL,
NULL);
}
So I tried WM_LBUTTONDOWN. I think this is something when the user click on the button the program will do something. I put in the switch(msg) case WM_LBUTTONDOWN:.
But no idea what's next.
Here is a simple demo to show how to detect click on a button, and change the color of button when you click on it.
#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")
#include "stdafx.h"
#include <windows.h>
#include <commctrl.h>
static BOOL flag = false;
ATOM RegisterWndClass(HINSTANCE hInst);
BOOL CreateMainWnd(HINSTANCE hInstance, int nCmdShow);
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
HINSTANCE hInst;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hInstPrev, LPWSTR lpszCmdLine,
int nCmdShow)
{
INITCOMMONCONTROLSEX icex = { 0 };
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_LISTVIEW_CLASSES | ICC_USEREX_CLASSES | ICC_BAR_CLASSES |
ICC_COOL_CLASSES | ICC_TAB_CLASSES | ICC_WIN95_CLASSES |
ICC_PROGRESS_CLASS | ICC_PAGESCROLLER_CLASS;
InitCommonControlsEx(&icex);
MSG msg;
hInst = hInstance;
if (!RegisterWndClass(hInstance))
return NULL;
if (!CreateMainWnd(hInstance, nCmdShow))
return NULL;
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
};
ATOM RegisterWndClass(HINSTANCE hInstance)
{
WNDCLASS wndClass = { 0 };
wndClass.style = CS_DBLCLKS;
wndClass.lpfnWndProc = MainWndProc;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = L"MainClass";
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
return RegisterClass(&wndClass);
}
BOOL CreateMainWnd(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd = CreateWindow(L"MainClass", L"Buttons sample",
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
GetSystemMetrics(SM_CXSCREEN) / 2 - 115,
GetSystemMetrics(SM_CYSCREEN) / 2 - 50,
230, 100, NULL, NULL, hInstance, NULL);
if (!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
HBITMAP hBitmap = NULL;
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
// Owner draw button
CreateWindow(L"BUTTON", L"", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON |
BS_OWNERDRAW, 10, 10, 60, 30, hWnd,
(HMENU)10001, hInst, NULL);
// Custom draw button
CreateWindow(L"BUTTON", L"", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 80,
10, 60, 30, hWnd, (HMENU)10002, hInst, NULL);
// Bitmap button
HWND hBitmapButton = CreateWindow(L"BUTTON", L"", WS_CHILD | WS_VISIBLE
| BS_PUSHBUTTON | BS_BITMAP,
150, 10, 60, 30, hWnd,
(HMENU)10003, hInst, NULL);
HDC hDC = GetDC(hWnd);
HDC hMemDC = CreateCompatibleDC(hDC);
hBitmap = CreateCompatibleBitmap(hDC, 55, 25);
SelectObject(hMemDC, hBitmap);
SetDCBrushColor(hMemDC, RGB(0, 0, 255));
RECT r = { 0 };
r.left = 0;
r.right = 55;
r.top = 0;
r.bottom = 25;
FillRect(hMemDC, &r, (HBRUSH)GetStockObject(DC_BRUSH));
DeleteDC(hMemDC);
ReleaseDC(hWnd, hDC);
SendMessage(hBitmapButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP,
(LPARAM)hBitmap);
return 0;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case 10001:
MessageBox(hWnd, L"Owner draw button clicked", L"Message", NULL);
return 0;
case 10002:
MessageBox(hWnd, L"Custom draw button clicked", L"Message", NULL);
return 0;
case 10003:
MessageBox(hWnd, L"Bitmap button clicked", L"Message", NULL);
return 0;
}
break;
// Owner draw button
case WM_DRAWITEM:
if (wParam == 10001)
{
if (flag == false)
{
LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam;
SetDCBrushColor(lpDIS->hDC, RGB(255, 0, 0));
SelectObject(lpDIS->hDC, GetStockObject(DC_BRUSH));
RoundRect(lpDIS->hDC, lpDIS->rcItem.left, lpDIS->rcItem.top,
lpDIS->rcItem.right, lpDIS->rcItem.bottom, 5, 5);
}
else
{
LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam;
SetDCBrushColor(lpDIS->hDC, RGB(0, 255, 0));
SelectObject(lpDIS->hDC, GetStockObject(DC_BRUSH));
RoundRect(lpDIS->hDC, lpDIS->rcItem.left, lpDIS->rcItem.top,
lpDIS->rcItem.right, lpDIS->rcItem.bottom, 5, 5);
}
flag = !flag;
return TRUE;
}
break;
// Custom draw button
case WM_NOTIFY:
switch (((LPNMHDR)lParam)->code)
{
case NM_CUSTOMDRAW:
if (((LPNMHDR)lParam)->idFrom == 10002)
{
LPNMCUSTOMDRAW lpnmCD = (LPNMCUSTOMDRAW)lParam;
switch (lpnmCD->dwDrawStage)
{
case CDDS_PREPAINT:
SetDCBrushColor(lpnmCD->hdc, RGB(0, 255, 0));
SetDCPenColor(lpnmCD->hdc, RGB(0, 255, 0));
SelectObject(lpnmCD->hdc, GetStockObject(DC_BRUSH));
SelectObject(lpnmCD->hdc, GetStockObject(DC_PEN));
RoundRect(lpnmCD->hdc, lpnmCD->rc.left + 3,
lpnmCD->rc.top + 3,
lpnmCD->rc.right - 3,
lpnmCD->rc.bottom - 3, 5, 5);
return TRUE;
}
}
break;
}
break;
case WM_DESTROY:
if (hBitmap != NULL)
DeleteObject((HBITMAP)hBitmap);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
Try to make some modifications to "if" conditions to meet your needs.

The Tab-key doesn't works in the child controls

The following is my winapi program that window contains 3 sets of controls:
The controls that created directly in the window
The controls in Group1
The controls in Group2
When I press Tab-key , it only traverse in set1.
Why I can't switch to the child control of the group1 and group2 by Tab-key?
#include <Windows.h>
LRESULT __stdcall WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message)
{
case WM_CTLCOLORSTATIC:
{
HDC hdcStatic = (HDC)wParam;
SetTextColor(hdcStatic, RGB(0, 0, 255));
SetBkMode(hdcStatic, TRANSPARENT);
return (LRESULT)GetStockObject(NULL_BRUSH);
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
////////////////////////////////////////////////////////////////////////////
void CreateEdit(const HWND &parent, const int &x, const int &y, const int &id) {
CreateWindow(L"EDIT", L"", WS_BORDER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, x, y, 200, 20, parent, (HMENU)id, NULL, NULL);
}
////////////////////////////////////////////////////////////////////////////
int __stdcall wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
WNDCLASSEX wndclass{};
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.hInstance = hInstance;
wndclass.hbrBackground = CreateSolidBrush(RGB(255, 128, 255));
wndclass.lpszClassName = L"test";
RegisterClassEx(&wndclass);
HWND hWndMainWindow = CreateWindow(
wndclass.lpszClassName,
L"test",
WS_EX_OVERLAPPEDWINDOW | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE,
100, 100, 500, 500,
NULL, NULL, hInstance, NULL);
::ShowWindow(hWndMainWindow, SW_SHOW);
::UpdateWindow(hWndMainWindow);
//Creating Controls~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int x = 10, y = 20, id = 100;
HWND g1 = CreateWindow(L"button", L"Group1", WS_CHILD | WS_VISIBLE | BS_GROUPBOX | WS_TABSTOP | WS_GROUP, 0, 50, 220, 200, hWndMainWindow, (HMENU)++id, NULL, NULL);
//Controls in Group1
CreateEdit(g1, x, (y += 30), ++id);
CreateEdit(g1, x, (y += 30), ++id);
CreateEdit(g1, x, (y += 30), ++id);
CreateEdit(g1, x, (y += 30), ++id);
HWND g2 = CreateWindow(L"button", L"Group2", WS_CHILD | WS_VISIBLE | BS_GROUPBOX | WS_TABSTOP | WS_GROUP, 260, 50, 220, 200, hWndMainWindow, (HMENU)++id, NULL, NULL);
y = 20;
//Controls in Group2
CreateEdit(g2, x, (y += 30), ++id);
CreateEdit(g2, x, (y += 30), ++id);
CreateEdit(g2, x, (y += 30), ++id);
CreateEdit(g2, x, (y += 30), ++id);
//The controls that create directly in the main window
y = 270;
CreateWindow(L"static", L"Main Window Controls", WS_CHILD | WS_VISIBLE, x, y, 200, 30, hWndMainWindow, (HMENU)++id, NULL, NULL);
CreateEdit(hWndMainWindow, x, (y += 30), ++id);
CreateEdit(hWndMainWindow, x, (y += 30), ++id);
CreateEdit(hWndMainWindow, x, (y += 30), ++id);
CreateEdit(hWndMainWindow, x, (y += 30), ++id);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) > 0) {
if (!IsDialogMessage(hWndMainWindow, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
}
The two child windows that host "Group1" and "Group2" both need to be marked as "control parents" with the WS_EX_CONTROLPARENT style. This style means:
The window itself contains child windows that should take part in
dialog box navigation. If this style is specified, the dialog manager
recurses into children of this window when performing navigation
operations such as handling the TAB key, an arrow key, or a keyboard
mnemonic
Change your code to create those windows as follows:
HWND g1 = CreateWindowEx(WS_EX_CONTROLPARENT, L"button", L"Group1", WS_CHILD | WS_VISIBLE | BS_GROUPBOX | WS_TABSTOP | WS_GROUP, 0, 50, 220, 200, hWndMainWindow, (HMENU)++id, NULL, NULL);
HWND g2 = CreateWindowEx(WS_EX_CONTROLPARENT, L"button", L"Group2", WS_CHILD | WS_VISIBLE | BS_GROUPBOX | WS_TABSTOP | WS_GROUP, 260, 50, 220, 200, hWndMainWindow, (HMENU)++id, NULL, NULL);
(As an aside, it seems wrong to make your windows children of the groupbox. They don't need to be - you can just position them inside it but make them siblings of it instead of children. The groupbox is specifically designed to work this way - I don't know how well it will work with the controls as children.)
Since you're not creating a dialog box, your main window should be created with the WS_EX_CONTROLPARENT style.
Make sure that you only place this style on your main window. The child windows should not be using this style.

Caused by EditControl or Clipboard?

OK, so i am writing this program in C++ that is supposed to append the clipboard text into the edit control inside the Auto-Clipboard tab. I have setup the program so that it supports unicode text.
The program appends the text correctly when i copy text outside the program. But if i copy text that is from the program, it shows me as if it is copying ansi characters that needs to be converted int unicode.
I am not sure if the problem is from the edit control or from the Clipboard. Is the edit control output not in unicode? Or is the clipboard copying as ansi and pasting as unicode?
Edit: So i find out that according to MSDN documentations, WM_COPY in edit controls are handled in CF_TEXT mode instead of CF_UNICODETEXT for the clipboard:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms649022(v=vs.85).aspx
And so, i added some subclassing starting with my AutoClipboardEdit control but for some reason i get currupted heap error on WM_DRAWCLIPBOARD messages. So i am stuck there:
Edit2: I got it working by not freeing the allocated memory of the text string used on the clipboard. In this case the name of the variable is hMem2. It seems that if i free hMem2, the program crashes with a "corrupted heap" error. My guess is that the OS itself manages and frees the memory. It does seem possible since the SetClipboardData argument for the data is a pointer. I also tried to test if memory actually leaked by sending a WM_COPY message into a infinite loop to see if the heap would increase forever; but far it didn't seem so.
So, i need someone to confirm to me that there is no memory leak or that the OS actually does manage and free the clipboard accordingly.
Here is the complete source code:
#define UNICODE
#define _UNICODE
#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")
#include <tchar.h>
#include <Windows.h>
#include <CommCtrl.h>
#include <sstream>
using namespace std;
TCHAR temp[1024];
enum TabIndexes
{
ID_ReadingPageTab,
ID_AutoClipboardTab
};
enum WindowControls
{
ID_SelectAll,
ID_TabControls,
ID_ReadingPageEdit,
ID_AutoClipboardEdit,
ID_AutoClipboardCheckbox,
ID_AutoReadCheckbox,
ID_AutoClearCheckbox,
ID_ReadPauseResumeButton,
ID_StopButton
};
//***************Global Variables***************
HWND MainWindowHandle;
HWND ClipboardViewer;
HWND TabControls;
HWND ReadingPageEdit;
HWND AutoClipboardEdit;
HWND AutoClipboardCheckbox;
HWND AutoReadCheckbox;
HWND AutoClearCheckbox;
HWND ReadPauseResumeButton;
HWND StopButton;
RECT WindowReactangle;
RECT EditControlsDimension;
HACCEL SelectAll;
int Textlength;
void ShowReport()
{
LPTSTR ErrorText = NULL;
FormatMessage
(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, //dwFlags
NULL, //lpSource
GetLastError(), //dwMessageId
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //dwLanguageId
(LPTSTR)&ErrorText, //lpBuffer
0, //nSize
NULL //*Arguments
);
MessageBox(NULL, ErrorText, TEXT("Last Error:"), MB_OK);
}
void OutputBox(LPTSTR OutputText)
{
MessageBox(NULL, OutputText, _T("WARNING!!!"), MB_OK);
}
WNDPROC OldProc;
LRESULT CALLBACK EditControl
(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
WPARAM StartOfSelectection;
LPARAM EndOfSelection;
int SelectionSize;
int TextSize;
TCHAR* hMem1;
TCHAR* hMem2;
if (uMsg == WM_COPY)
{
OpenClipboard(NULL);
SendMessage(hwnd, EM_GETSEL, (WPARAM)&StartOfSelectection, (LPARAM)&EndOfSelection);
SelectionSize = EndOfSelection - StartOfSelectection + 1;
TextSize = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
TextSize -= (TextSize - EndOfSelection - 1);
hMem1 = new TCHAR[TextSize]();
ZeroMemory(hMem1, TextSize*sizeof(TCHAR));
SendMessage(hwnd, WM_GETTEXT, TextSize, (LONG)hMem1);
hMem2 = new TCHAR[SelectionSize]();
ZeroMemory(hMem2, SelectionSize*sizeof(TCHAR));
for(int Index=0; StartOfSelectection<EndOfSelection; ++StartOfSelectection)
hMem2[Index++] = hMem1[StartOfSelectection];
SetClipboardData(CF_UNICODETEXT, (HANDLE)hMem2);
CloseClipboard();
delete[] hMem1;
//delete[] hMem2;
}
return OldProc(hwnd, uMsg, wParam, lParam);
}
void CreateControls(HWND hWndParent)
{
GetClientRect(hWndParent, &WindowReactangle);
const INITCOMMONCONTROLSEX CommonControls = {sizeof(INITCOMMONCONTROLSEX), ICC_TAB_CLASSES};
InitCommonControlsEx(&CommonControls);
TabControls = CreateWindow
(
WC_TABCONTROL, //lpClassName
NULL, //lpWindowName
WS_VISIBLE | WS_CHILD, //dwStyle
WindowReactangle.left, //x
WindowReactangle.top, //y
WindowReactangle.right, //nWidth
WindowReactangle.bottom - 100, //nHeight
hWndParent, //hWndParent
(HMENU)ID_TabControls, //hMenu
NULL, //hInstance
NULL //lpParam
);
TCITEM TabItemStructure = {0};
TabItemStructure.mask = TCIF_TEXT;
TabItemStructure.pszText = _T("Reading Page");
SendMessage(TabControls, TCM_INSERTITEM, ID_ReadingPageTab, (LPARAM)&TabItemStructure);
TabItemStructure.pszText = _T("Auto-Clipboard");
SendMessage(TabControls, TCM_INSERTITEM, ID_AutoClipboardTab, (LPARAM)&TabItemStructure);
ACCEL AcceleratorStructure;
AcceleratorStructure.fVirt = FCONTROL | FVIRTKEY;
AcceleratorStructure.key = 0x41;
AcceleratorStructure.cmd = ID_SelectAll;
SelectAll = CreateAcceleratorTable(&AcceleratorStructure, 1);
ReadingPageEdit = CreateWindow
(
_T("EDIT"), //lpClassName
NULL, //lpWindowName
WS_VISIBLE | WS_CHILD | WS_VSCROLL | WS_BORDER | ES_MULTILINE, //dwStyle
5, //x
30, //y
WindowReactangle.right - 10, //nWidth
WindowReactangle.bottom - 135, //nHeight
TabControls, //hWndParent
(HMENU)ID_ReadingPageEdit, //hMenu
NULL, //hInstance
NULL //lpParam
);
AutoClipboardEdit = CreateWindow
(
_T("EDIT"), //lpClassName
NULL, //lpWindowName
WS_CHILD | WS_VSCROLL | WS_BORDER | ES_MULTILINE, //dwStyle
5, //x
30, //y
WindowReactangle.right - 10, //nWidth
WindowReactangle.bottom - 135, //nHeight
TabControls, //hWndParent
(HMENU)ID_AutoClipboardEdit, //hMenu
NULL, //hInstance
NULL //lpParam
);
AutoClipboardCheckbox = CreateWindow
(
_T("BUTTON"), //lpClassName
_T("Auto-Clipboard"), //lpWindowName
BS_AUTOCHECKBOX | WS_VISIBLE | WS_CHILD, //dwStyle
10, //x
WindowReactangle.bottom -100 +10, //y
150, //nWidth
25, //nHeight
hWndParent, //hWndParent
(HMENU)ID_AutoClipboardCheckbox, //hMenu
NULL, //hInstance
NULL //lpParam
);
SendMessage(AutoClipboardCheckbox, BM_CLICK, TRUE, 0);
OldProc = (WNDPROC)SetWindowLongPtr(AutoClipboardEdit, GWLP_WNDPROC, (LONG)EditControl);
AutoReadCheckbox = CreateWindow
(
_T("BUTTON"), //lpClassName
_T("Auto-Read"), //lpWindowName
BS_AUTOCHECKBOX | WS_VISIBLE | WS_CHILD, //dwStyle
10, //x
WindowReactangle.bottom -100 +35, //y
150, //nWidth
25, //nHeight
hWndParent, //hWndParent
(HMENU)ID_AutoReadCheckbox, //hMenu
NULL, //hInstance
NULL //lpParam
);
AutoClearCheckbox = CreateWindow
(
_T("BUTTON"), //lpClassName
_T("Auto-Clear"), //lpWindowName
BS_AUTOCHECKBOX | WS_VISIBLE | WS_CHILD, //dwStyle
10, //x
WindowReactangle.bottom -100 +60, //y
150, //nWidth
25, //nHeight
hWndParent, //hWndParent
(HMENU)ID_AutoReadCheckbox, //hMenu
NULL, //hInstance
NULL //lpParam
);
}
LRESULT WINAPI MainWindowProcedure
(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
//Clipboard Events
case WM_CHANGECBCHAIN:
if ((HWND)wParam == ClipboardViewer)
ClipboardViewer = (HWND)lParam;
return 0;
case WM_DRAWCLIPBOARD:
OpenClipboard(NULL);
SendMessage(AutoClipboardEdit, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
SendMessage(AutoClipboardEdit, EM_REPLACESEL, 0, (LPARAM)GetClipboardData(CF_UNICODETEXT)); //CF_TEXT //CF_UNICODETEXT
CloseClipboard();
break;
//Window Controls Events
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_SelectAll:
if (HIWORD(wParam)==1)
SendMessage(GetFocus(), EM_SETSEL, (WPARAM)0, (LPARAM)-1);
break;
case ID_AutoClipboardCheckbox:
if (SendMessage(AutoClipboardCheckbox, BM_GETCHECK, 0, 0) == BST_CHECKED)
ClipboardViewer = SetClipboardViewer(hwnd);
else
ChangeClipboardChain(hwnd, ClipboardViewer);
break;
}
return 0;
//Tab Controls Events
case WM_NOTIFY:
if (SendMessage(TabControls, TCM_GETCURSEL, 0, 0))
{
ShowWindow(ReadingPageEdit, SW_HIDE);
ShowWindow(AutoClipboardEdit, SW_SHOW);
} else
{
ShowWindow(AutoClipboardEdit, SW_HIDE);
ShowWindow(ReadingPageEdit, SW_SHOW);
}
break;
//Main Window Events
case WM_SIZE:
{
int LOPARAM = lParam & 0xFFFF;
int HIPARAM = lParam >> 16;
SetWindowPos(TabControls, NULL, 0, 0, LOPARAM, HIPARAM-100, SWP_DRAWFRAME);
SetWindowPos(ReadingPageEdit, NULL, 5, 30, LOPARAM-10, HIPARAM-100-35, SWP_DRAWFRAME);
SetWindowPos(AutoClipboardEdit, NULL, 5, 30, LOPARAM-10, HIPARAM-100-35, SWP_DRAWFRAME);
SetWindowPos(AutoClipboardCheckbox, NULL, 10, HIPARAM-100+10, 150, 25, SWP_DRAWFRAME);
SetWindowPos(AutoReadCheckbox, NULL, 10, HIPARAM-100+35, 150, 25, SWP_DRAWFRAME);
SetWindowPos(AutoClearCheckbox, NULL, 10, HIPARAM-100+60, 150, 25, SWP_DRAWFRAME);
return 0;
}
case WM_CREATE:
CreateControls(hwnd);
return 0;
case WM_DESTROY:
DestroyAcceleratorTable(SelectAll);
ChangeClipboardChain(hwnd, ClipboardViewer);
PostQuitMessage(ERROR_SUCCESS);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void CreateMainWindow()
{
WNDCLASSEX WindowClassStructure;
WindowClassStructure.cbSize = sizeof(WNDCLASSEX);
WindowClassStructure.style = CS_HREDRAW | CS_VREDRAW;
WindowClassStructure.lpfnWndProc = MainWindowProcedure;
WindowClassStructure.cbClsExtra = 0;
WindowClassStructure.cbWndExtra = 0;
WindowClassStructure.hInstance = NULL;
WindowClassStructure.hIcon = LoadIcon(NULL, IDI_INFORMATION);
WindowClassStructure.hCursor = LoadCursor(NULL, IDC_ARROW);
WindowClassStructure.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
WindowClassStructure.lpszMenuName = NULL;
WindowClassStructure.lpszClassName = _T("MainClass");
WindowClassStructure.hIconSm = LoadIcon(NULL, IDI_INFORMATION);
RegisterClassEx(&WindowClassStructure);
MainWindowHandle = CreateWindow
(
_T("MainClass"), //lpClassName
_T("Clipboard Reader"), //lpWindowName
WS_VISIBLE | WS_OVERLAPPEDWINDOW, //dwStyle
CW_USEDEFAULT, //x
CW_USEDEFAULT, //y
640, //nWidth
480, // nHeight
NULL, //hWndParent
NULL, //hMenu
NULL, //hInstance
NULL //lpParam
);
}
int WINAPI _tWinMain
(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow
)
{
CreateMainWindow();
MSG MessageStructure = {0};
while(MessageStructure.message != WM_QUIT)
{
if (PeekMessage(&MessageStructure, NULL, 0, 0, PM_REMOVE))
{
if (!TranslateAccelerator(MainWindowHandle, SelectAll, &MessageStructure))
{
TranslateMessage(&MessageStructure);
DispatchMessage(&MessageStructure);
}
}
}
return MessageStructure.wParam;
}

Parent Window creation

I know it is a very simple question but i currently cant create a parent window...
My code:
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
static HWND paste;
static HWND update_list;
/*HWND changeuser = CreateWindow(0, 0,
0,
0, 0, x, y,
0, (HMENU)changeuser2, 0, NULL); */
switch(msg)
{
case WM_CREATE:
meniu(hwnd);
CreateWindow(TEXT("static"), TEXT("\nSuckers online:"),
WS_VISIBLE | WS_CHILD | SS_CENTER,
0, 0, x, 55,
hwnd, (HMENU)delete, NULL, NULL);
connected = CreateWindow(TEXT("edit"), TEXT(""),
WS_VISIBLE | WS_CHILD | WS_VSCROLL| ES_MULTILINE ,
0, 60, x, 340,
hwnd, (HMENU)delete2, NULL, NULL);
CreateWindow(TEXT("static"), TEXT(""),
WS_VISIBLE | WS_CHILD | SS_CENTER|BS_PUSHBUTTON,
0, 405, x, 358,
hwnd, (HMENU) delete3, NULL, NULL);
paste = CreateWindow(TEXT("Edit"), TEXT("Paste the ip here"),
WS_VISIBLE | WS_CHILD | SS_CENTER,
x/2 - 60, 410, 120, 40,
hwnd, (HMENU) ip, NULL, NULL);
CreateWindow(TEXT("Button"), TEXT("Connect!"),
WS_VISIBLE | WS_CHILD | SS_CENTER | BS_PUSHBUTTON,
x/2 - 120, 450, 120, 40,
hwnd, (HMENU) connect2, NULL, NULL);
update_list = CreateWindow(TEXT("Button"), TEXT("Update the list!"),
WS_VISIBLE | WS_CHILD | SS_CENTER | BS_PUSHBUTTON,
x/2, 450, 120, 40,
hwnd, (HMENU) update, NULL, NULL);
_beginthread( lista, 0, (void*)(0) );//begin thread lista
break;
case WM_CTLCOLORSTATIC : {
HBRUSH br = CreateSolidBrush(RGB(80,67,77)); // change background color
SetTextColor((HDC)wParam,RGB(0,102,51)); //the controls text color
return (LRESULT) br;
}
case WM_COMMAND:
switch LOWORD(wParam)
{
case exit:
PostQuitMessage(0);
break;
case ip:
int nr;
nr = GetWindowTextLength(paste);
if (nr >= 17)
SetWindowText(paste, "");
break;//omor textul, ca sa pot sa fac paste
case connect2:
GetWindowText(paste,adresa,16);
_beginthread( start, 0, (void*)(0) ); //as\ici se face conexiunea principala
//DestroyWindow(hwnd);
MessageBox(0,"Connected with the user","Ok",0);
break;
case update:
exit2 = true;
Sleep(100);
SetWindowText(connected,"");
_beginthread( lista, 0, (void*)(0) );//begin thread lista
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
I want the other windows created to be the child of the changeuser window...
I just cant make it happen...
Any help will be appreciated!
To change the window of a parent, use SetParent().
But i would think about the structure - if you need to change the parent of one or more windows in a normal dialog setting, it is likely these windows should have a different parent.
In your case there is a problem in your handling of window messages though:
If your message handler receives WM_DESTROY you call PostQuitMessage(), which probably results in your application closing.
There are two ways you can handle that:
use different window processes for your main dialog and child dialogs (preferably)
or use the hwnd parameter to decide wether you call PostQuitMessage()
You can't 'replace' a window. If you need to tear down and replace your main window, delete it and make a new one. Windows only get the parent flag when they have children, not because you tell them to.