error LNK1120: 1 unresolved external - VS13 C [duplicate] - c

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 6 years ago.
I have tried to compile this code:
#include <windows.h>
#include <commctrl.h>
#define ID_TABCTRL 1
#define ID_EDIT 2
#define BTN_ADD 3
#define BTN_DEL 4
#define BTN_CLR 5
#define MAX_TAB_LEN 15
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HWND hTab, hEdit;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR pCmdLine, int nCmdShow) {
MSG msg;
WNDCLASSW wc = { 0 };
wc.lpszClassName = L"Tab control";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClassW(&wc);
CreateWindowW(wc.lpszClassName, L"Tab control",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 380, 230, 0, 0, hInstance, 0);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
WINCOMMCTRLAPI BOOL WINAPI InitCommonControlsEx(_In_ const INITCOMMONCONTROLSEX *picce);
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
TCITEMW tie;
wchar_t text[4];
LRESULT count, id;
INITCOMMONCONTROLSEX icex;
switch (msg) {
case WM_CREATE:
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_TAB_CLASSES;
InitCommonControlsEx(&icex);
hTab = CreateWindowW(WC_TABCONTROLW, NULL, WS_CHILD | WS_VISIBLE,
0, 0, 200, 150, hwnd, (HMENU)ID_TABCTRL, NULL, NULL);
hEdit = CreateWindowW(WC_EDITW, NULL, WS_CHILD | WS_VISIBLE | WS_BORDER,
250, 20, 100, 25, hwnd, (HMENU)ID_EDIT, NULL, NULL);
SendMessage(hEdit, EM_SETLIMITTEXT, MAX_TAB_LEN, 0);
CreateWindowW(WC_BUTTONW, L"Add", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
250, 50, 100, 25, hwnd, (HMENU)BTN_ADD, NULL, NULL);
CreateWindowW(WC_BUTTONW, L"Delete", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
250, 80, 100, 25, hwnd, (HMENU)BTN_DEL, NULL, NULL);
CreateWindowW(WC_BUTTONW, L"Clear", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
250, 110, 100, 25, hwnd, (HMENU)BTN_CLR, NULL, NULL);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case BTN_ADD:
GetWindowTextW(hEdit, text, 250);
if (lstrlenW(text) != 0) {
tie.mask = TCIF_TEXT;
tie.pszText = text;
count = SendMessageW(hTab, TCM_GETITEMCOUNT, 0, 0);
SendMessageW(hTab, TCM_INSERTITEMW, count,
(LPARAM)(LPTCITEM)&tie);
}
break;
case BTN_DEL:
id = SendMessageW(hTab, TCM_GETCURSEL, 0, 0);
if (id != -1) {
SendMessageW(hTab, TCM_DELETEITEM, 0, id);
}
break;
case BTN_CLR:
SendMessageW(hTab, TCM_DELETEALLITEMS, 0, 0);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return(DefWindowProcW(hwnd, msg, wParam, lParam));
}
and it seems like this libary:
#include <commctrl.h>
giving me the following error:
error LNK2019: unresolved external symbol __imp__InitCommonControlsEx#4 referenced in function _WndProc#16 C:\Users\User\Desktop\Magshimim\Magshimim EX1\Magshimim EX1\01.obj Magshimim EX1
now the code is an example code from here: http://zetcode.com/gui/winapi/advancedcontrols/
so i figured out that something wrong with my compiler...
can any one help me find the problem and correct it?
edit:
the question is not a duplicate because the refereed duplicate talks in a very general way about the error itself and as a beginner i dont have the skills to build a proper answer from such a question and because that code is been used by many peoples who check the example i think its impotent to make a specific question

Either add #pragma comment(lib, "comctl32.lib") or adjust the linker settings to link against comctl32.lib.
You can check the table at the bottom of a function's MSDN article to find out, which library you are required to link against. Every Windows application is linked against kernel32.dll and every GUI application against user32.dll. Anything else needs to be specified explicitly1.
1 There are exceptions, check IInspectable's comment below.

Related

Win32 API Disable User Input in Drop Down / Combobox

This sample code I found online has a list dropdown menu, and when I click the text box that the items are displayed in, it doesn't allow me to type anything into the box. This is the behavior I want for my own code. However when I paste in the relevant parts of this code into my own, my program is allowing me to type characters into the Drop Down box. I can't find a single flag in this code that is causing the user input to be disabled, but it only works properly here and not in my code for some reason.
I even tried commenting out certain lines of the code to see if they were responsible for disabling user input, but it is still disabled. Yet in my code, no matter what I do, I can type additional characters into the list box as if it were any other text field. I can't figure out what I'm missing.
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hinst;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR lpCmdLine, int nCmdShow) {
HWND hwnd;
MSG msg ;
WNDCLASS wc = {0};
wc.lpszClassName = "Application";
wc.hInstance = hInstance ;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc ;
wc.hCursor = LoadCursor(0,IDC_ARROW);
g_hinst = hInstance;
RegisterClass(&wc);
hwnd = CreateWindow(wc.lpszClassName, "Combo box",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 270, 170, 0, 0, hInstance, 0);
while (GetMessage(&msg, NULL, 0, 0)) {
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
static HWND hwndCombo;
//static HWND hwndStatic;
const char *items[] = { "FreeBSD", "OpenBSD",
"NetBSD", "Solaris", "Arch" };
switch(msg) {
case WM_CREATE:
hwndCombo = CreateWindow("Combobox", NULL,
WS_CHILD | WS_VISIBLE | CBS_DROPDOWN,
10, 10, 120, 200, hwnd, NULL, g_hinst, NULL);
// CreateWindowW(L"Button", L"Drop down",
// WS_CHILD | WS_VISIBLE,
// 150, 10, 90, 25, hwnd, (HMENU) 1, g_hinst, NULL);
// hwndStatic = CreateWindowW(L"Static", L"",
// WS_CHILD | WS_VISIBLE,
// 150, 80, 90, 25, hwnd, NULL, g_hinst, NULL);
for (int i = 0; i < 4; i++ ) {
SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) items[i]);
}
break;
case WM_COMMAND:
// if (HIWORD(wParam) == BN_CLICKED) {
// SendMessage(hwndCombo, CB_SHOWDROPDOWN, (WPARAM) TRUE, 0);
// }
if (HIWORD(wParam) == CBN_SELCHANGE) {
LRESULT sel = SendMessage(hwndCombo, CB_GETCURSEL, 0, 0);
// SetWindowTextW(hwndStatic, items[sel]);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
There is no special handling, no character limit flags, no additional source code or headers, or resource files, nothing...
I've read this code over and over and I just don't understand what is causing this program to present the dropdown items as read-only text.
My code is pretty much identical with just some additional switch statements and functions, but the functionality of the combo box should be the same. Is there some other global flag in a program that could cause user input where it shouldn't be allowed?
Use the CBS_DROPDOWNLIST style on the ComboBox to remove the writable edit control
hwndCombo = CreateWindow("Combobox", NULL,
WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST,
10, 10, 120, 200, hwnd, NULL, g_hinst, NULL);
Per the documentation:
Combo Box Styles
To create a combo box using the CreateWindow or CreateWindowEx function, specify the COMBOBOX class, appropriate window style constants, and a combination of the following combo box styles.
Constant
Description
...
...
CBS_DROPDOWN
Similar to CBS_SIMPLE, except that the list box is not displayed unless the user selects an icon next to the edit control.
CBS_DROPDOWNLIST
Similar to CBS_DROPDOWN, except that the edit control is replaced by a static text item that displays the current selection in the list box.
...
...
CBS_SIMPLE
Displays the list box at all times. The current selection in the list box is displayed in the edit control.
...
...

In WIndows API, under what "event" do I put child control creation or why aren't my controls appearing?

It's been years since I last worked with Windows API and I'm trying my hand at it again. I have a simple Window (with title "Test"). I put in the Window message handler under WM_CREATE, 2 CreateWindow calls to create a static and an edit control. I'm pretty sure the coordinates are decent (not overlapping or off the window rectangle). Am I putting the calls under the wrong event? It's just a simple window - not MDI or SDI or anything like that. Here is my code for the entire program. I hope it's sufficient to figure out what I'm doing wrong. I'm using Eclipse CDT with Cygwin's G++ compiler to build it....:
#include <windows.h>
BOOL InitApplication(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE hinstance, int nCmdShow);
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL InitApplication(HINSTANCE hInstance)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = "";
wc.lpszClassName = "MainWindow";
return(RegisterClass(&wc));
}
BOOL InitInstance(HINSTANCE hinstance, int nCmdShow)
{
HINSTANCE hCurInstance = hinstance;
HWND hWnd = CreateWindow("MainWindow", "Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, (HWND)(NULL), (HMENU)(NULL), hCurInstance, (LPVOID)(NULL));
if(!hWnd)
return(FALSE);
// Show the window and send a WM_PAINT message to the window
// procedure.
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return(TRUE);
}
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CREATE:
CreateWindow("WC_STATIC", "&Test: ", SS_LEFT | WS_VISIBLE | WS_CHILD, 10, 10, 50, 20, hWnd, NULL, (HINSTANCE)(GetWindowLongPtr(hWnd, GWLP_HINSTANCE)), (LPVOID)(NULL));
CreateWindow("WC_EDIT", "", WS_BORDER | WS_TABSTOP | WS_VISIBLE | WS_CHILD | ES_LEFT, 60, 10, 50, 20, hWnd, NULL, (HINSTANCE)(GetWindowLongPtr(hWnd, GWLP_HINSTANCE)), (LPVOID)(NULL));
return(0);
default:
return(DefWindowProcA(hWnd, uMsg, wParam, lParam));
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmd, int nCmdShow)
{
BOOL fGotMessage;
MSG msg;
if(!InitApplication(hInstance))
return(FALSE);
if(!InitInstance(hInstance, nCmdShow))
return(FALSE);
while(((fGotMessage = GetMessage(&msg, (HWND) NULL, 0, 0)) != 0) && (fGotMessage != -1))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return(msg.wParam);
}
WM_CREATE is the correct "event" message to create the child controls in.
You are simply using the wrong class names for the child controls. That is why you are not seeing them. Had you checked the result of those CreateWindow() calls for failures, you would have noticed that CreateWindow() was returning NULL, and GetLastError() was reporting ERROR_CANNOT_FIND_WND_CLASS (1407).
You need to replace "WC_STATIC" with "Static", and replace "WC_EDIT" with "Edit". Or, you can use the pre-defined WC_STATIC and WC_EDIT constants that are defined in <commctrl.h>.
You can also replace GetWindowLongPtr(hWnd, GWLP_HINSTANCE) with NULL when creating system-defined classes, as they are registered globally, not per-module. The HINSTANCE parameter of CreateWindow/Ex() is ignored for them.
On a side note: your GetMessage() loop can be simplified to just:
while (GetMessage(&msg, (HWND) NULL, 0, 0))
See: When will GetMessage return -1?

Same _exact_ code in C and D give different results -- why?

When I run this C code:
// Get rid of the CRT and stuff; we don't need it
#pragma comment(linker, "/Entry:mainCRTStartup")
#pragma comment(linker, "/NoDefaultLib:msvcrt.lib")
#pragma comment(linker, "/NoDefaultLib:kernel32.lib")
#pragma comment(linker, "/NoDefaultLib:ntdll.lib")
#pragma comment(linker, "/Subsystem:Console")
#pragma comment(lib, "user32.lib")
#include <windows.h>
int mainCRTStartup()
{
MSG msg;
HWND hWndParent;
WNDCLASS wndClass =
{
0, &DefWindowProc, 0, 0, NULL, NULL, LoadCursor(NULL, IDC_ARROW),
GetSysColorBrush(COLOR_3DFACE), NULL, TEXT("MyClass")
};
RegisterClass(&wndClass);
hWndParent = CreateWindow(
wndClass.lpszClassName, NULL, WS_VISIBLE | WS_OVERLAPPEDWINDOW,
0, 0, 33, 100, NULL, NULL, NULL, NULL);
CreateWindow(TEXT("Button"), wndClass.lpszClassName,
WS_VISIBLE | WS_CHILD | BS_GROUPBOX,
5, 5, 100, 50, hWndParent, NULL, NULL, NULL);
while (GetMessage(&msg, hWndParent, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
I get:
But when I run the equivalent D code:
// Again, get rid of the runtime
pragma(startaddress, mainCRTStartup);
pragma(lib, "dmd_win32.lib");
import win32.windows;
int mainCRTStartup()
{
MSG msg;
HWND hWndParent;
WNDCLASS wndClass =
{
0, &DefWindowProc, 0, 0, NULL, NULL, LoadCursor(NULL, IDC_ARROW),
GetSysColorBrush(COLOR_3DFACE), NULL, "MyClass"
};
RegisterClass(&wndClass);
hWndParent = CreateWindow(
wndClass.lpszClassName, NULL, WS_VISIBLE | WS_OVERLAPPEDWINDOW,
0, 0, 33, 100, NULL, NULL, NULL, NULL);
CreateWindow("Button", wndClass.lpszClassName,
WS_VISIBLE | WS_CHILD | BS_GROUPBOX,
5, 5, 100, 50, hWndParent, NULL, NULL, NULL);
while (GetMessage(&msg, hWndParent, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
I get:
I'm so confused... what can possibly be causing this white background?!
Edit:
I'm not sure it's actually a library bug... I just removed the dependency (and I don't see anything wrong with the code), but the problem is still there:
version = Unicode;
extern(Windows):
alias void* HWND, HMENU, HINSTANCE, HCURSOR, HBRUSH, HICON;
alias ushort ATOM, WORD;
alias uint UINT, DWORD;
alias int[2] POINT;
alias int BOOL;
alias int LONG;
alias size_t WPARAM, LPARAM, LRESULT;
alias char* LPSTR;
alias const(char)* LPCSTR;
alias wchar* LPWSTR;
alias const(wchar)* LPCWSTR;
version(Unicode)
{
alias LPCWSTR LPCTSTR;
alias LPWSTR LPTSTR;
alias GetMessageW GetMessage;
alias CreateWindowExW CreateWindowEx;
alias DispatchMessageW DispatchMessage;
alias DefWindowProcW DefWindowProc;
alias LoadCursorW LoadCursor;
alias RegisterClassW RegisterClass;
alias WNDCLASSW WNDCLASS;
}
else
{
alias LPCSTR LPCTSTR;
alias LPSTR LPTSTR;
alias GetMessageA GetMessage;
alias CreateWindowExA CreateWindowEx;
alias DispatchMessageA DispatchMessage;
alias DefWindowProcA DefWindowProc;
alias LoadCursorA LoadCursor;
alias RegisterClassA RegisterClass;
alias WNDCLASSA WNDCLASS;
}
LPCTSTR MAKEINTATOM(ATOM atom) { return cast(LPCTSTR)atom; }
ATOM RegisterClassA(WNDCLASSA*);
ATOM RegisterClassW(WNDCLASSW*);
HCURSOR LoadCursorA(HINSTANCE, LPCSTR);
HCURSOR LoadCursorW(HINSTANCE, LPCWSTR);
LRESULT DefWindowProcA(HWND, UINT, WPARAM, LPARAM);
LRESULT DefWindowProcW(HWND, UINT, WPARAM, LPARAM);
BOOL GetMessageA(const(MSG)*, HWND, UINT, UINT);
BOOL GetMessageW(const(MSG)*, HWND, UINT, UINT);
LONG DispatchMessageA(const(MSG)*);
LONG DispatchMessageW(const(MSG)*);
BOOL TranslateMessage(const(MSG)*);
HWND CreateWindowExA(int, LPCSTR, LPCSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, void*);
HWND CreateWindowExW(int, LPCWSTR, LPCWSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, void*);
HBRUSH GetSysColorBrush(int);
alias LRESULT function(HWND, UINT, WPARAM, LPARAM) WNDPROC;
enum
{
NULL = null,
COLOR_3DFACE = 15,
BS_GROUPBOX = 7,
}
const LPCTSTR IDC_ARROW = cast(LPCTSTR)32512;
struct MSG
{
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
}
struct WNDCLASSA
{
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
}
struct WNDCLASSW
{
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCWSTR lpszMenuName;
LPCWSTR lpszClassName;
}
enum
{
WS_OVERLAPPED = 0,
WS_TILED = WS_OVERLAPPED,
WS_MAXIMIZEBOX = 0x00010000,
WS_MINIMIZEBOX = 0x00020000,
WS_TABSTOP = 0x00010000,
WS_GROUP = 0x00020000,
WS_THICKFRAME = 0x00040000,
WS_SIZEBOX = WS_THICKFRAME,
WS_SYSMENU = 0x00080000,
WS_HSCROLL = 0x00100000,
WS_VSCROLL = 0x00200000,
WS_DLGFRAME = 0x00400000,
WS_BORDER = 0x00800000,
WS_CAPTION = 0x00c00000,
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,
WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW,
WS_MAXIMIZE = 0x01000000,
WS_CLIPCHILDREN = 0x02000000,
WS_CLIPSIBLINGS = 0x04000000,
WS_DISABLED = 0x08000000,
WS_VISIBLE = 0x10000000,
WS_MINIMIZE = 0x20000000,
WS_ICONIC = WS_MINIMIZE,
WS_CHILD = 0x40000000,
WS_CHILDWINDOW = 0x40000000,
WS_POPUP = 0x80000000,
WS_POPUPWINDOW = WS_POPUP|WS_BORDER|WS_SYSMENU,
}
pragma(startaddress, mainCRTStartup);
int mainCRTStartup()
{
MSG msg;
HWND hWndParent;
WNDCLASS wndClass =
{
0, &DefWindowProc, 0, 0, NULL, NULL, LoadCursor(NULL, IDC_ARROW),
GetSysColorBrush(COLOR_3DFACE), NULL, "MyClass"
};
ATOM atom = RegisterClass(&wndClass);
hWndParent = CreateWindowEx(
0, wndClass.lpszClassName, NULL, WS_VISIBLE | WS_OVERLAPPEDWINDOW,
0, 0, 33, 100, NULL, NULL, NULL, NULL);
CreateWindowEx(0, "Button", wndClass.lpszClassName,
WS_VISIBLE | WS_CHILD | BS_GROUPBOX,
5, 5, 100, 50, hWndParent, NULL, NULL, NULL);
while (GetMessage(&msg, hWndParent, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
Either I'm doing something wrong, or it's a compiler bug... but even if it's a compiler bug, I still have no idea how something like this can happen, because it would need to call very specific APIs! Ideas?
This is subsystem version issue (linker responsibility). Add -L/SUBSYSTEM:CONSOLE:4.0 to dmd command line to fix MyClass background color. Walter likes old systems so default OPTLINK subsystem version is 3.10. Looks like Microsoft's link 9.0 use 5.0 as default subsystem version.
Linux guy here so I will do my best:
It looks like a problem with the library itself. My guess is you got it from here?
https://github.com/AndrejMitrovic/DWinProgramming
In this case the solution is to contact the fellow who wrote the dmd win32 library you are using. If you compiled them from source then certainly there is a way to contact that person. It appears you have found a bug!
PS: One other possibility if you compiled the libraries from source. You may have a compile argument or flag that is different and causes the difference. Also, perhaps it is a compatibility issue with a library dependency. In this case the answer is still to contact the developer of the library. He will probably ask you for some compile output.

TabControl clips client area when displaying overflow arrows

This bug appears only with common control v6 (theme enabled) on XP (seems to work on 7 and 2008). I wonder if someone else might have seen this bug feature.
When you have a single-line TabControl with lots of tabs, a pairs of arrows should appear if there is not enough space to display all the tabs. This is all nice except that the client area is also clipped, which is not nice at all.
Have I miss something ? I played with tabcontrol's window style, but no luck so far.
To illustrate this, it's actually best to see it in action:
#define UNICODE
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
HWND htab, hbut;
int WINAPI WinMain (HINSTANCE instance,
HINSTANCE previnst,
LPSTR args,
int wndState)
{
int i;
MSG messages;
WNDCLASSEX wincl = {
.hInstance = instance, .lpszClassName = L"WindowsApp",
.lpfnWndProc = WindowProcedure, .style = CS_DBLCLKS, .cbSize = sizeof wincl,
.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1)
};
InitCommonControls();
wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
if (!RegisterClassEx (&wincl))
return 0;
HWND hwnd = CreateWindow(L"WindowsApp", L"Windows App", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, NULL, instance, NULL);
htab = CreateWindowEx(WS_EX_CONTROLPARENT, WC_TABCONTROL,
L"MyTab", WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, 10, 10, 514, 325, hwnd,
(HMENU) 10, instance, NULL);
hbut = CreateWindow(
WC_BUTTON, L"My nice button that is clipped", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
10, 30, 494, 285, htab, (HMENU) IDOK, instance, NULL
);
for (i = 0; i < 10; i ++)
{
WCHAR myBuf[100];
TCITEM tc = {.mask = TCIF_TEXT, .pszText = myBuf};
wsprintf(myBuf, L"My super tab %d", i + 1);
TabCtrl_InsertItem(htab, i, &tc);
}
SendMessage(hbut, WM_SETFONT, (LPARAM) GetStockObject(DEFAULT_GUI_FONT), FALSE);
SendMessage(htab, WM_SETFONT, (LPARAM) GetStockObject(DEFAULT_GUI_FONT), FALSE);
ShowWindow(hwnd, wndState);
while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return messages.wParam;
}
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
RECT r;
switch (message) {
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_SIZE:
GetClientRect(hwnd, &r);
MoveWindow(htab, 10, 10, r.right-20, r.bottom - 20, TRUE);
MoveWindow(hbut, 10, 30, r.right-40, r.bottom - 60, TRUE);
break;
case WM_COMMAND:
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
Unfortunately I can't test it (I have Win7) but according to http://msdn.microsoft.com/en-us/library/hh298367%28v=VS.85%29.aspx you need to have clip siblings on the tab control and also the parent window. You could also try using the tab control's adjust rect message to get the positions for your button.

How do I create a normal win32 edit control?

I'm trying to create an edit control with the regular 3D border around it (in the classic windows style, anyway), but it just has a 1px black border around it. Here is my CreateWindowEx call:
return CreateWindowEx(0, "EDIT", "E:\\bk",
WS_VISIBLE | WS_CHILD | WS_BORDER | ES_LEFT,
87, 81, 150, 17,
main_window.hwnd,
(HMENU)5, hInstance, NULL);
If I exclude WS_BORDER then it's just a white box. Any ideas on what's wrong here?
Update
WS_EX_CLIENTEDGE did the trick.
I don't know anything about manifest files, or how to make the window use the more modern windows themes (XP, for example), instead of the chunky 3D borders. But, when I do learn all that, will WS_EX_CLIENTEDGE make them use those themes instead, or will it enforce the 3D look?
Try using WS_EX_CLIENTEDGE. That will create an inset 3-D window border under typical situations.
return CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "E:\\bk",
WS_VISIBLE | WS_CHILD | WS_BORDER | ES_LEFT,
87, 81, 150, 17,
main_window.hwnd,
(HMENU)5, hInstance, NULL);
Also see the following link for the rest of the available flags for CreateWindowEx.
CreateWindowEx at MSDN
He is right WS_EX_CLIENTEDGE will do the 3D border.
I think you mean the 'WS_EX_DLGMODALFRAME' style. It makes it look like the old-style 3d raised type look. Combined with 'WS_BORDER' to make it look a like a 3d border around the control.
Below code Creates an input box and a button, when clicked updates title.
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int main() {
HINSTANCE hInstance;
MSG msg;
WNDCLASSW wc = {0};
wc.lpszClassName = L"Edit control";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClassW(&wc);
CreateWindowW(wc.lpszClassName, L"Edit control",
WS_OVERLAPPEDWINDOW | WS_VISIBLE, 220, 220, 280, 200, 0, 0,
hInstance, 0);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
static HWND hwndEdit;
HWND hwndButton;
switch (msg) {
case WM_CREATE:
hwndEdit = CreateWindowW(L"Edit", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER,
50, 50, 150, 20, hwnd, (HMENU)102, NULL, NULL);
hwndButton = CreateWindowW(L"button", L"Set title", WS_VISIBLE | WS_CHILD,
50, 100, 80, 25, hwnd, (HMENU)103, NULL, NULL);
break;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED) {
int len = GetWindowTextLengthW(hwndEdit) + 1;
wchar_t text[len];
GetWindowTextW(hwndEdit, text, len);
SetWindowTextW(hwnd, text);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
To compile:
g++ test.cpp -o test.exe -mwindows
source: zetcode.com/editcontrol

Resources