C++ WindowsApp LNK2028Error - c++

When I compile the following code in Visual Studio 2019 I receive the following error code: code of the error output. It seems to be a LNK2028 error but I do not understand what is happening. Can someone explain why I receive this error?
Here is my code:
#include "MyForm.h"
#include <windows.h>
#include <windowsx.h>
#include <winuser.h>
#include <tchar.h>
using namespace System;
using namespace System::Windows::Forms;
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
HWND p = FindWindowEx(hwnd, NULL, _T("SHELLDLL_DefView"), false);
HWND* ret = (HWND*)lParam;
if (p) {
// Gets the WorkerW Window after the current one.
*ret = FindWindowEx(NULL, hwnd, _T("WorkerW"), NULL);
}
return true;
}
HWND get_wallpaper_window()
{
// Fetch the Progman window
HWND progman = FindWindow(_T("ProgMan"), NULL);
// Send 0x052C to Progman. This message directs Progman to spawn a
// WorkerW behind the desktop icons. If it is already there, nothing
// happens.
SendMessageTimeout(progman, 0x052C, 0, 0, SMTO_NORMAL, 1000, NULL);
// We enumerate all Windows, until we find one, that has the SHELLDLL_DefView
// as a child.
// If we found that window, we take its next sibling and assign it to workerw.
HWND wallpaper_hwnd = NULL;
EnumWindows(EnumWindowsProc, (LPARAM)&wallpaper_hwnd);
// Return the handle you're looking for.
return wallpaper_hwnd;
}
[STAThread]
void main(array<String^>^ args)
{
Application::EnableVisualStyles;
Application::SetCompatibleTextRenderingDefault(false);
DEM0::MyForm form;
Application::Run(% form);
}

As mentioned in this and this post it seems like the issue is due to a linker error which is caused by (I believe 8 function calls) that are depending on libraries implemented by the User32.dll located in C:\windows\system32 more info about this.
In this current project it seems like you are missing to include additional dependencies. You can include those by going to Project Properties -> Linker -> Input -> Additional Dependencies. Here you can choose to include the User32.dll file or choose the "Inherit from parent or project defaults" option. I believe this will solve your linker errors.

Related

Error LINK2019, something about main? [duplicate]

Error:
Severity Code Description Project File Line Error LNK2019 unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ)
Severity Code Description Project File Line
Error LNK1120 1 unresolved externals
Code:
#include "windows.h"
#include "tchar.h"
#include "d3d9.h"
#pragma comment(lib, "d3d9.lib")
LPDIRECT3D9 pDirect3D=NULL;
LPDIRECT3DDEVICE9 pDirect3DDevice=NULL;
const int segment = 50;
const int NV = segment*13;
struct CUSTOMVERTEX
{
float x, y, z, rhv;
DWORD color;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
LPDIRECT3DVERTEXBUFFER9 pVertexBuffer=NULL;
HRESULT InitialDirect3D(HWND hvnd)
{
if((pDirect3D=Direct3DCreate9(D3D_SDK_VERSION))==NULL)
return E_FAIL;
D3DDISPLAYMODE Display;
if(FAILED(pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Display)))
return E_FAIL;
D3DPRESENT_PARAMETERS Direct3DParameter;
ZeroMemory(&Direct3DParameter, sizeof Direct3DParameter);
Direct3DParameter.Windowed=TRUE;
Direct3DParameter.SwapEffect=D3DSWAPEFFECT_DISCARD;
Direct3DParameter.BackBufferFormat=Display.Format;
if(FAILED(pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hvnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&Direct3DParameter, &pDirect3DDevice)))
return E_FAIL;
return S_OK;
}
HRESULT RenderingDirect3D()
{
if(pDirect3DDevice==NULL)
return E_FAIL;
pDirect3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(90, 150, 100), 1.f, 0);
pDirect3DDevice->BeginScene();
pDirect3DDevice->SetStreamSource(0, pVertexBuffer, 0, sizeof(CUSTOMVERTEX));
pDirect3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
pDirect3DDevice->DrawPrimitive(D3DPT_LINELIST, 0, NV);
pDirect3DDevice->EndScene();
pDirect3DDevice->Present(NULL, NULL, NULL, NULL);
return S_OK;
}
void DeleteDirect3D()
{
if(pVertexBuffer)
pVertexBuffer->Release();
if(pDirect3DDevice)
pDirect3DDevice->Release();
if(pDirect3D)
pDirect3D->Release();
}
HRESULT InitialVertexBuffer()
{
float u = 0.0;
int z = 0;
float points[][2] = {
{150,150},
{125,100},
{150,50},
{200,50},
{225,55},
{285,60},
{325,25},
{342,30},
{340,35},
{340,40},
{325,75},
{300,125},
{300,175},
{305,250},
{295,287},
{257,347},
{200,350},
{150,325},
{140,290},
{142,282},
{160,280},
{165,286},
{175,325},
{215,340},
{250,335},
{275,300},
{275,250},
{255,200},
{250,150},
{275,100},
{305,65},
{275,85},
{240,95},
{215,85},
{170,65},
{140,90},
{160,135},
{160,150},
{152.5,150},
{150,150}
};
CUSTOMVERTEX Vertexes[NV*2];
int i = 0;
while( i < NV*2 )
{
u = 0.f;
for(int j = 0; j < segment; j++)
{
Vertexes[i].x = (1-3*u+3*u*u-u*u*u)*points[z][0]+(3*u-6*u*u+3*u*u*u)*points[z+1][0]+(3*u*u-3*u*u*u)*points[z+2][0]+(u*u*u)*points[z+3][0];
Vertexes[i].y = (1-3*u+3*u*u-u*u*u)*points[z][1]+(3*u-6*u*u+3*u*u*u)*points[z+1][1]+(3*u*u-3*u*u*u)*points[z+2][1]+(u*u*u)*points[z+3][1];
Vertexes[i].z = 0.5f;
Vertexes[i].color = 0x00ffffff;
Vertexes[i].rhv = 1.f;
u += (float)1/segment;
i++;
Vertexes[i].x = (1-3*u+3*u*u-u*u*u)*points[z][0]+(3*u-6*u*u+3*u*u*u)*points[z+1][0]+(3*u*u-3*u*u*u)*points[z+2][0]+(u*u*u)*points[z+3][0];
Vertexes[i].y = (1-3*u+3*u*u-u*u*u)*points[z][1]+(3*u-6*u*u+3*u*u*u)*points[z+1][1]+(3*u*u-3*u*u*u)*points[z+2][1]+(u*u*u)*points[z+3][1];
Vertexes[i].z = 0.5f;
Vertexes[i].color = 0x00ffffff;
Vertexes[i].rhv = 1.f;
i++;
}
z += 3;
}
if(FAILED(pDirect3DDevice->CreateVertexBuffer(NV*2*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &pVertexBuffer, NULL)))
return E_FAIL;
void *pVB=NULL;
if(FAILED(pVertexBuffer->Lock(0, sizeof Vertexes, (void**)&pVB, 0)))
return E_FAIL;
memcpy(pVB, Vertexes, sizeof Vertexes);
pVertexBuffer->Unlock();
return S_OK;
}
LRESULT CALLBACK MainWinProc(HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam)
{
switch(msg)
{
case WM_PAINT:
RenderingDirect3D();
ValidateRect(hwnd, NULL);
break;
case WM_DESTROY:
DeleteDirect3D();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{
WNDCLASSEX windowsclass;
HWND hwnd;
MSG msg;
//
windowsclass.cbSize=sizeof(WNDCLASSEX);
windowsclass.style=CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
windowsclass.lpfnWndProc=MainWinProc;
windowsclass.cbClsExtra=0;
windowsclass.cbWndExtra=0;
windowsclass.hInstance=hinstance;
windowsclass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
windowsclass.hCursor=LoadCursor(NULL, IDC_ARROW);
windowsclass.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
windowsclass.lpszMenuName=NULL;
windowsclass.lpszClassName=_T("WINDOWSCLASS");
windowsclass.hIconSm=LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&windowsclass))
return 0;
if(!(hwnd=CreateWindowEx(
NULL,
_T("WINDOWSCLASS"),
_T("Desenam litera G"),
WS_OVERLAPPEDWINDOW|WS_VISIBLE,
CW_USEDEFAULT, 0,
CW_USEDEFAULT, 0,
NULL,
NULL,
hinstance,
NULL)))
return 0;
if(SUCCEEDED(InitialDirect3D(hwnd)))
{
if(SUCCEEDED(InitialVertexBuffer()))
{
ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd);
ZeroMemory(&msg, sizeof msg);
while(msg.message!=WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
RenderingDirect3D();
}
}
}
return msg.wParam;
}
Check project configuration. Linker->System->SubSystem should be Windows.
If you use CMake you have to set WIN32 flag in add_executable
add_executable(${name} WIN32 ${source_files})
See CMake Doc for more information.
I had same Problem when i was trying to create executable from program that having no main() method. When i included sample main() method like this
int main(){
return 0;
}
It solved
Right click on project. Properties->Configuration Properties->General->Linker.
I found two options needed to be set.
Under System: SubSystem = Windows (/SUBSYSTEM:WINDOWS)
Under Advanced: EntryPoint = main
I faced the same problem too and I found out that I selected "new Win32 application" instead of "new Win32 console application". Problem solved when I switched. Hope this can help you.
just add:
int main()
{
//you can leave it empty
return 0;
}
to your project and everything will work
its causes because of visual studio try to find the main function to start the project and didn't found it
Similar to #仲耀晖 I had the wrong application type configured for a dll. I guess that the project type changed due to some bad copy pasting, as #Daniel Struhl suggested.
How to verify:
Right click on the project -> properties -> Configuration Properties -> General -> Project Defaults -> Configuration Type.
Check if this field contains the correct type, e.g. "Dynamic Library (.dll)" in case the project is a dll.
This is an edge case, but you can also get this error if you are building an MFC application with CMake.
In that case, you need to add the following definitions:
ADD_DEFINITIONS(-D_AFXDLL)
SET(CMAKE_MFC_FLAG 2) # or 1 if you are looking for the static library
If you are compiling with unicode, the following properties also need to be added:
set_target_properties(MyApp PROPERTIES
COMPILE_DEFINITIONS
_AFXDLL,_UNICODE,UNICODE,_BIND_TO_CURRENT_CRT_VERSION,_BIND_TO_CURRENT_MFC_VERSION
LINK_FLAGS "/ENTRY:\"wWinMainCRTStartup\""
)
Soure: FAQ: How to use MFC with CMake
Select the project. Properties->Configuration Properties->Linker->System.
My problem solved by setting below option.
Under System: SubSystem = Console(/SUBSYSTEM:CONSOLE)
Or you can choose the last option as "inherite from the parent".
This worked for me:
(I don't have enough rep to embed pictures yet -- sorry about this.)
I went into Project --> Properties --> Linker --> System.
IMG: Located here, as of Dec 2019 Visual Studio for Windows
My platform was set to Active(Win32) with the Subsystem as "Windows".
I was making a console app, so I set it to "Console".
IMG: Changing "Windows" --> "Console"
Then, I switched my platform to "x64".
IMG: Switched my platform from Active(32) to x64
Solution for me is: I clean both the solution and the project. And just rebuild the project.
This error happens because I tried to delete the main file (only keep library files) in the previous build so at the current build the old stuff is still kept in the built directory. That's why unresolved things happened.
"unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ) "
I had to #include <tchar.h> in my windows service application.
I left it as a windows console type subsystem.
The "Character Set" was set to UNICODE.
I deleted the file with main() function in my project when I wanted to change project type to static library.
I Forgot to change Properties -> General -> Configuration Type
from
Application(.exe)
to
Static Library (.lib)
This too gave me the same error.
Old thread but for me it started working (after following all advise above) when i renamed int main(void) to int wmain(void) and removed WIN23 from cmake's add_executable().
If it is a windows system, then it may be because you are using 32 bit winpcap library in a 64 bit pc or vie versa. If it is a 64 bit pc then copy the winpcap library and header packet.lib and wpcap.lib from winpcap/lib/x64 to the winpcap/lib directory and overwrite the existing
The problem might originate from a macro instruction in SDL_main.h
In that macro your main(){} is renamed to SDL_main(){} because SDL needs its own main(){} on some of the many platforms they support, so they change yours. Mostly it achieves their goal, but on my platform it created problems, rather than solved them. I added a 2nd line in SDL_main.h, and for me all problems were gone.
#define main SDL_main //Original line. Renames main(){} to SDL_main(){}.
#define main main //Added line. Undo the renaming.
If you don't like the compiler warning caused by this pair of lines, comment both lines out.
If your code is in WinApp(){} you don't have this problem at all. This answer only might help if your main code is in main(){} and your platform is similar to mine.
I have: Visual Studio 2019, Windows 10, x64, writing a 32 bit console app that opens windows using SDL2.0 as part of a tutorial.
I got the same error because I created a new object from a templated class using the template name without specifying the type explicitly like this:
int main()
{
MyClass<T> Test2(5.60, 6.6); <- This is wrong
^^^
return 0;
}
The correct way to do it was to specify exactly what T was like this:
int main()
{
MyClass<double> Test2(5.60, 6.6); <- This is right
^^^^^^
return 0;
}
for me adding .dll file to my project folder solved this error.
but game me another error: "unresolved external symbol main referenced in function ..." and I solved this by following this answer. https://stackoverflow.com/a/50087608/10903596 or in short adding #define SDL_MAIN_HANDLED in my main file or file containing main function.
You can get this error, if you have your main entry point enclosed in a namespace.
So, don't put your main entry point in a namespace, leave it at the global level.
I wanted to start working with SDL library. After setting and checking the include and library paths for numerous times, I came across the answer by Rinus Verdult here. I added this line after the #include lines and it worked.
#define main main
I have visual studio 2019, windows 10 64bit.

Filtering/Parsing list produced from EnumWindows in C++

I am using the following code to get a list of windows running on my machine
#include <iostream>
#include <windows.h>
using namespace std;
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
TCHAR buffer[512];
SendMessage(hwnd, WM_GETTEXT, 512, (LPARAM)(void*)buffer);
wcout << buffer << endl;
return TRUE;
}
int main()
{
EnumWindows(EnumWindowsProc, NULL);
return 0;
}
I want to get a list of what is normally refered to as a Window - I say this because when running the above code I get a list of around 40 entries, most of these are not what I would call windows.
Here is an excerpt of the output produced by running the above script on my machine, out of the 5 entries only Microsoft Visual Studio is a Window
...
Task Switching
Microsoft Visual Studio
CiceroUIWndFrame
Battery Meter
Network Flyout
...
How can I go about filtering/parsing this data, as there is not anything to use as an identifier.
I would use EnumDesktopWindows to enumerate all top-level windows in your desktop; you may even use the IsWindowsVisible API during the enumeration process, to filter non-visible windows out.
This compilable C++ code works fine for me (note that here I showed how to pass some additional info to the enumeration proc, in this case using a pointer to a vector<wstring>, in which the window titles are stored for later processing):
#include <windows.h>
#include <iostream>
#include <string>
#include <vector>
using std::vector;
using std::wcout;
using std::wstring;
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
if (!IsWindowVisible(hwnd))
{
return TRUE;
}
wchar_t titleBuf[512];
if (GetWindowText(hwnd, titleBuf, _countof(titleBuf)) > 0)
{
auto pTitles = reinterpret_cast<vector<wstring>*>(lParam);
pTitles->push_back(titleBuf);
}
return TRUE;
}
int main()
{
vector<wstring> titles;
EnumDesktopWindows(nullptr, EnumWindowsProc, reinterpret_cast<LPARAM>(&titles));
for (const auto& s : titles)
{
wcout << s << L'\n';
}
}
Define what you call a Window and query the windows handle for the correct properties. Use GetWindowLong() with for example GWL_HWNDPARENT to test if there's no parent window or if the parent window is the desktop window. Additional test may be needed, e.g. you can use the (extended) window styles. See also here for additional ideas on usable tests.

Properly Link Libraries in the Command Line

Preface: I'm fairly new to C++ and am just beginning to seriously program.
Post-Preface: I tried to post a link for the functions/pages I mention in this post, but Stack Overflow yelled at me because I don't have enough reputation to post more than two links.
I'm attempting to make a few simple GUIs in C++ with the Windows API using MinGW and the command line. I'm trying to change the window background, and one function which helps do this is the CreateSolidBrush function. This function requires the gdi32 library, but each time I try to compile/link to this library, I receive an error along the lines of "can't find that library, sucka".
Page1 and page2 provide useful information about MinGW's library functionality. Stack Overflow post # 5683058 and # 17031290 describe what I think are similar questions/problems to mine. I've searched far and wide for a simple and direct answer about how to link files/libraries from other directories (especially Windows libraries), but no luck in implementing the knowledge from these pages. Perhaps the answer is staring me right in the face, but my valiant efforts to "see the cat, draw the tiger" are in vain. It's possible that I'm entering the incorrect path/name (lib vs dll?), or maybe I'm completely overlooking something more fundamental (missing a header?). One command I've tried to use is
g++ -LC:\WINDOWS\System32 -lgdi32 gui.cpp
but this doesn't seem to work (note: source file named "gui.cpp").
Question 1: To start simple, what is the proper notation/command to link to individual header/source files which are not in the current directory?
Question 2: What is the proper notation/command to link to a library which is in the current directory?
Question 3: What is the proper notation/command to link to a library which is not in the current directory?
I realize these questions are sorta-kinda answered in a variety of ways on other pages, but they're often mingled with directions regarding Visual Studio, Eclipse, Code::Blocks, etc. and therefore unclear for the novices who forgo the luxuries of an IDE. I would appreciate a straightforward answer for your typical, run-of-the-mill noob. Many thanks in advance for any help or guidance.
I'll post my code, but I'm thinking only a couple of the first five lines are relevant:
#include <windows.h>
#include <string>
COLORREF desired_color = RGB(200,200,200);
HBRUSH hBrush = CreateSolidBrush(desired_color);
static char str_class_name[] = "MyClass";
static char str_titlebar[] = "My Window Title";
static int window_width = 300;
static int window_height = 300;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static HINSTANCE program_global_instance = NULL;
int WINAPI WinMain(HINSTANCE program_current_instance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
program_global_instance = program_current_instance;
WNDCLASSEX window_class;
HWND window_handle;
MSG window_message;
window_class.cbSize = sizeof(WNDCLASSEX); // size of struct; always set to size of WndClassEx
window_class.style = 0; // window style
window_class.lpfnWndProc = WndProc; // window callback procedure
window_class.cbClsExtra = 0; // extra memory to reserve for this class
window_class.cbWndExtra = 0; // extra memory to reserve per window
window_class.hInstance = program_global_instance; // handle for window instance
window_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); // icon displayed when user presses ALT+TAB
window_class.hCursor = LoadCursor(NULL, IDC_ARROW); // cursor used in the program
window_class.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // brush used to set background color
window_class.lpszMenuName = NULL; // menu resource name
window_class.lpszClassName = str_class_name; // name with which to identify class
window_class.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // program icon shown in taskbar and top-left corner
if(!RegisterClassEx(&window_class)) {
MessageBox(0, "Error Registering Class!", "Error!", MB_ICONSTOP | MB_OK);
return 0;
}
window_handle = CreateWindowEx(
WS_EX_STATICEDGE, // dwExStyle: window style
str_class_name, // lpClassName: pointer to class name
str_titlebar, // lpWindowName: window titlebar
WS_OVERLAPPEDWINDOW, // dwStyle: window style
CW_USEDEFAULT, // x: horizontal starting position
CW_USEDEFAULT, // y: vertical starting position
window_width, // nWidth: window width
window_height, // nHeight: window height
NULL, // hWndParent: parent window handle (NULL for no parent)
NULL, // hMenu: menu handle (Null if not a child)
program_global_instance, // hInstance : current window instance
NULL // lpParam -Points to a value passed to the window through the CREATESTRUCT structure.
);
if (window_handle == NULL) {
MessageBox(0, "Error Creating Window!", "Error!", MB_ICONSTOP | MB_OK);
return 0;
}
ShowWindow(window_handle, nCmdShow);
UpdateWindow(window_handle);
while(GetMessage(&window_message, NULL, 0, 0)) {
TranslateMessage(&window_message);
DispatchMessage(&window_message);
}
return window_message.wParam;
}
// window_handle: window ID
// uMsg: window message
// wParam: additional message info; depends on uMsg value
// lParam: additional message info; depends on uMsg value
LRESULT CALLBACK WndProc(
HWND window_handle,
UINT Message,
WPARAM wParam,
LPARAM lParam
) {
switch(Message) {
case WM_CLOSE:
DestroyWindow(window_handle);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(window_handle, Message, wParam, lParam);
}
return 0;
}
Question 1: To start simple, what is the proper notation/command to link to individual header/source files which are not in the current directory?
That's not linking, that's compiling/including (unless you compile those source files to object files, first).
So:
gcc {other options} -o gui.exe gui.cpp /path/to/source_file_one.cpp /path/to/source_file_n.cpp
or, compile the others first:
gcc {other options} -c -o source_file_one.o /path/to/source_file_one.cpp
gcc {other options} -c -o source_file_n.o /path/to/source_file_n.cpp
gcc {other options} -o gui.exe source_file_n.o source_file_one.o gui.cpp
-c tells gcc not to try and link things together, as this is done in the last step.
{other options} can contain -I{include dirs} to inform gcc where to look when you #include something.
Question 2: What is the proper notation/command to link to a library which is in the current directory?
See 3; -L. should work.
Question 3: What is the proper notation/command to link to a library which is not in the current directory?
You're doing it right, so far: -L tells gcc about paths to look into for libraries, and -l{libname} links against a library.

Push button and combo box WinAPI

I am trying to do some windows programming. I created a combo box and a push button. My objective is, when the user selects an item in the combo box, the button is activated and needs to be clicked to proceed. I have done something like this so far:
This is how i create the combo box:
Func.h
#ifndef FUNCS_H
#define FUNCS_H
// Winapi headers....
#include <windows.h>
#include <windowsx.h>
#include <shlobj.h>
//created lib
#include "Resource.h"
// Standard C/C++ headers...
#include <iostream>
#include <string>
#include <dirent.h> // directory manipulation....
#include <cstring>
#include <fstream>
using std::cout;
using std::endl;
using std::string;
using std::ofstream;
HWND hselectOK;
HWND hComboBox1;
void createControls(HWND hwnd) // Create our combo box
{
HWND hselectFeature;
HINSTANCE hInstance = GetModuleHandle(NULL);
// Create our List box
hComboBox1 = CreateWindow(WC_COMBOBOX,"", CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD |WS_OVERLAPPED |WS_VISIBLE , 7, 20, 300, 100, hwnd, NULL, hInstance, NULL);
SendMessage(hComboBox1, CB_ADDSTRING, 0,(LPARAM)"Histogram of Oriented Gradients (HOG)");
SendMessage(hComboBox1, CB_ADDSTRING, 0,(LPARAM)"Scale Invariant Feature Transform (SIFT)");
SendMessage(hComboBox1, CB_ADDSTRING, 0,(LPARAM)"Speeded Up Robust Features (SURF)");
// SendMessage(hComboBox1, CB_SETCURSEL, (WPARAM)2,(LPARAM)0); //CB_SETCURSEL
// Create our push bottons
hselectFeature = CreateWindow("STATIC", "Select Feature", SS_LEFT | WS_CHILD, 320,20, 100, 21,hwnd, (HMENU)1, hInstance, NULL);
ShowWindow(hselectFeature,1);
hselectOK = CreateWindow("BUTTON", "Ok", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON | WS_DISABLED, 320,45, 100, 21,hwnd, NULL, hInstance, NULL);
}
#endif // FUNCS_H
WinProc.h
#ifndef WINPROC_H
#define WINPROC_H
// Winapi Headers
#include <CommDlg.h>
#include <winuser.h>
// OpenCV headers
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
// Standard C/C++ headers
#include <iostream>
#include <string>
// Created headers;
#include "Funcs.h"
#include "Resource.h"
using std::cout;
using std::endl;
using std::string;
using namespace cv;
int classNumber;
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
string dirPath;
int comboIndex;
switch (message) /* handle the messages */
{
case WM_CREATE:
createControls(hwnd);
break;
case WM_COMMAND:
{
switch(HIWORD(wParam))
{
case CBN_SELCHANGE: // When user select item in combo box, enable the button.
{
EnableWindow(hselectOK, TRUE); // enable the button
}
break;
case BN_CLICKED: // When user has chosen a list, the button is used to proceed with further task associated to the selected item.
{
char listName[200];
comboIndex = SendMessage(hComboBox1, (UINT) CB_GETCURSEL, 0, 0);
SendMessage(hComboBox1, (UINT)CB_GETLBTEXT, (WPARAM)comboIndex, (LPARAM)listName);
if(comboIndex == 0)
{
MessageBox(hwnd,listName, "You chose", MB_OK);
// Want to Do some function here.
}
else if(comboIndex == 1)
{
MessageBox(hwnd,listName, "You chose", MB_OK);
// Want to Do some function here.
}
else if(comboIndex == 2)
{
MessageBox(hwnd,listName, "You chose", MB_OK);
// Want to Do some function here.
}
}
break;
}
switch LOWORD(wParam)
{
case IDM_IMG_PATH:
{
dirPath = browseFolder(hwnd);
DialogBox(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_CLASS),hwnd, ClassDlgProcedure);
createClassLabelFile(hwnd, dirPath, classNumber);
return 0;
}
case IDM_EXIT:
{
PostMessage(hwnd, WM_CLOSE,0 , 0);
}
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;
}
#endif // WINPROC_H
Those part are only some of the relevant parts of the code.
The problem is, when I exit the program using the case IDM_EXIT, the message box under the case BN_CLICKED always appears and then the program closes. I am expecting that when we close the program, no such message box would appear, but this is not the case. What I'm saying is, the message box appears twice, once when you select click the button and when you want to close the program. Why is that happening. Any Ideas or suggestions ?
The problem is that you are assuming that WM_COMMAND is a message that is unique to your ComboBox, Which is not.
Take a look at this old but gold blog post.
Quoting from the author,
The high-order word of the wParam parameter "specifies the
notification code if the message is from a control". What does
"control" mean here? Remember that you have to take things in context.
The WM_COMMAND message is being presented in the context of Win32 in
general, and in the context of the window manager in particular.
Windows such as edit boxes, push buttons, and list boxes are commonly
called "controls", as are all the window classes in the "common
controls library". In the world of the window manager, a "control" is
a window whose purpose is to provide some degree of interactivity
(which, in the case of the static control, might be no interactivity
at all) in the service of its parent window. The fact that the
WM_COMMAND is used primarily in the context of dialog boxes further
emphasizes the point that the term "control" here is just a synonym
for "child window".
To summarize, any button click inside your application window will translate as a WM_COMMAND with a BN_CLICKED wParam. This includes the close button of the window.
To handle specific clicks from your combo box you have two options. The easy way is to filter the hWnd of the control that sent the message, you should already know the window handle of your combo box and it shouldn't be a problem to compare against it.
The other option is to define your own messages and check against those in your WndProc handler. The web is full of examples of how to define your own application/control specific messages.
When you click your 'Exit' menu, windows also send a 'BN_CLICKED' message to the 'WindowProcedure' function and that is why the message box appears. You should use an ID for the button rather than making the 'hmenu' parameter 'NULL' like this:
hselectOK = CreateWindow("BUTTON", "Ok", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON | WS_DISABLED, 320,45, 100, 21,hwnd,
(HMENU)305, // Here is the ID of your button ( You may use your own ID )
hInstance, NULL);
And you have to add some ID checking code in your 'case BN_CLICKED' like that:
case BN_CLICKED: // When user has chosen a list, the button is used to proceed with further task associated to the selected item.
{
// You must do this check otherwise the message box will appear again when you click the 'Exit' menu
if ( LOWORD(wParam) == 305 ) // '305' is the ID which I have used as the button ID in above code
{
// Now add your click event code here
}
}
break;

Browse For Folder dialog window handle C++

How to get the handle HWND of the dialog which user open when clicking on a button.
I'm using Spy++ to find the window class and tittle, but it says that no such window is found. And how then to get the handle of that dialog in C++ using Win API ?
I hope that I will be able to do that using simple functions as FindWindow, GetParent, any WIN APi function. I do not like to inject something or load DLL. Thanks
UPDATE:
the folder browser dialog is opened by other program. I want to get it's handle from different program , my program. Thanks.
The closest to want i need is for now the function WindowFromPoint
Accessibility will let you capture window creation events from other processes without DLL injection. You can modify the example to accommodate for the browsing window specifically. Here's an example I made previously to test that is based on the one from the article. Modify it however you wish:
#include <iostream>
#include <windows.h>
void CALLBACK proc(HWINEVENTHOOK hook, DWORD event, HWND hwnd, LONG obj, LONG child, DWORD thr, DWORD time) {
if (hwnd && obj == OBJID_WINDOW && child == CHILDID_SELF) {
switch (event) {
case EVENT_OBJECT_CREATE: {
std::cout << "Window created!\n";
break;
}
case EVENT_OBJECT_DESTROY: {
std::cout << "Window destroyed!\n";
break;
}
}
}
}
int main() {
HWINEVENTHOOK hook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_DESTROY, nullptr, proc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (hook) {
UnhookWinEvent(hook);
}
}