In my C program's menu I have a Help section.
When pressed, it should open a help file.
I used Helpinator Professional to make a simple help file.
Now, pre-history:
I tried using the WinHelp() method by including <winuser.h>. It opened the file, but it gave me an error, saying that the file is not a Windows Help file or is corrupted. Then I read that WinHelp() is outdated and I should use HtmlHelp() instead by including <htmlhelp.h>. I included it by writing the full path to it, because wxDev-C++'s directories in compiler settings are not included normally and I don't exactly know how it checks the directories.
I included in my resources.h file.
Code in switch statement:
case ID_Help:
HtmlHelp(hwnd, "file location", HH_DISPLAY_TOPIC, 0);
break;
This gives me an error, saying that it is undeclared. Then, I declared HWMD help; before the switch statement and changed code to:
case ID_Help:
help = HtmlHelp(hwnd, "file location", HH_DISPLAY_TOPIC, 0);
break;
And it still tells me that it is undeclared.
What should I do? I'm stuck. I also encountered other problems on the way, some of them mentioned above, but nevermind them for now.
Source code:
#include "resources.h"
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char window_class[] = "WindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
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 = hThisInstance;
wincl.lpszClassName = window_class;
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 = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_HAND);
wincl.lpszMenuName = MAKEINTRESOURCE (ID_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 color as the background of the window */
wincl.hbrBackground = (HBRUSH) (COLOR_BACKGROUND + 2);
/* 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*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
window_class, /* Classname */
"Slacker Tracker v0.1", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
600, /* The programs width */
600, /* 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 */
);
MessageBox(NULL, "Message box #1 at your service.", "MESSAGE BOX #1", 0);
/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);
/* 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)
{
LPCTSTR name = "D:\\winapi\\1\\help.chm";
HANDLE file;
int size;
char buffer[100];
wchar_t error[256];
HWND help;
switch (message) /* handle the messages */
{
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_File_Exit:
PostMessage(hwnd, WM_CLOSE, 0, 0);
break;
case ID_NewMsgBox:
MessageBox(NULL, "Message box #3 at your service", "MESSAGE BOX #3", 0);
break;
case ID_Help:
//WinHelp(hwnd, "D:\\winapi\\1\\help.chm", HELP_INDEX, 0);
help = HtmlHelp(hwnd, "D:\\winapi\\1\\help.chm", HH_DISPLAY_TOPIC, 0);
break;
case ID_FSize:
file = CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (file == INVALID_HANDLE_VALUE){
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), error, 255, NULL);
MessageBoxW(NULL, error, (LPCWSTR)L"file", 0);
}
else{
size = GetFileSize(file, NULL);
itoa(size, buffer, 10);
MessageBox(NULL, buffer, "File Size", MB_OK);
}
CloseHandle(file);
break;
}
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd, "Message box #2 at your service", "MESSAGE BOX #2", 0);
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;
}
Compile log:
main.c: In function 'WindowProcedure':
main.c:99:36: error: 'HtmlHelp' undeclared (first use in this function)
main.c:99:36: note: each undeclared identifier is reported only once for each function it appears in
You should add this line to your .cpp file.
#include "htmlhelp.h"
Then you need to assign the event to call help. (this is where I think it is stating that it is undefined)
void CTestHelpDlg::OnHelp()
{
HtmlHelp(this->m_hWnd, "HelpSample.chm", HH_DISPLAY_TOPIC, NULL);
}
Further documentation and the tutorial I used for learning this is here
http://www.codeguru.com/cpp/w-p/help/html/article.php/c6503/Starting-Out-with-HtmlHelp.htm
Related
Am doing a small project in cpp using codeblocks ide on my windows 8.1 machine. Adding the menu was fine and even I went as far as adding some common controls like button, static, edit based on some of my notes from online sources.
main.cpp
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <winuser.h>
#define BTN_BUTTON 201
#define CMB_COMBOBOX 202
#define LST_LISTBOX 203
#define TXT_TEXTBOX 204
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char szClassName[ ] = "CodeBlocksWindowsApp";
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 = 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 = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* 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) COLOR_BACKGROUND;
/* 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*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Code::Blocks Template Windows App", /* 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_CREATE:
CreateWindow ("combobox", NULL,
WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST,
20, 10, 400, 120,
hwnd, (HMENU)CMB_COMBOBOX, GetModuleHandle(NULL), NULL);
// If you uncomment the function below that I used to create a listbox see my program does not compile
/*
CreateWindow ("listbox", NULL,
WS_CHILD | WS_VISIBLE | LBS_NOTIFY | LBS_COMBOBOX,
20, 40, 140, 120,
hwnd, (HMENU)LST_LISTBOX, GetModuleHandle(NULL), NULL);
*/
CreateWindow("edit", NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL| ES_MULTILINE | ES_AUTOHSCROLL,
170, 40, 250, 120,
hwnd, (HMENU)TXT_TEXTBOX, GetModuleHandle(NULL), NULL);
CreateWindow("button", "Submit This",
WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
300, 170, 120, 30,
hwnd, (HMENU)BTN_BUTTON, GetModuleHandle(NULL), NULL);
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;
}
Now everything on my code works perfect if I omit the code for the listbox which i dearly want to be part of my code. In the function for creating ListBox the compile comments
error: "LBS_COMBOBOX" was not declared in this scope
yet it is okay with LBS_NOTIFY. I would appreciate if someone enlightened me on an issue prventing my cpp program from running. Am still a newbie in this and I could have overlooked on something.
This is the editted version
You should not be using LBS_COMBOBOX anyway, it is a internal style used by Windows:
The combo box itself must set this style. If the style is set by anything but the combo box, the list box will regard itself incorrectly as a child of a combo box and a failure will result.
Maybe your SDK does not include a define for this style because you should never be setting it.
Here is a quick one to help yoou create a listbox based on a tutorial on a link here http://winapi.foosyerdoos.org.uk/index.php
HWND CreateListbox(const HWND hParent,const HINSTANCE hInst,DWORD dwStyle, const RECT& rc,const int id,const ustring& caption)
{
//dwStyle|=WS_CHILD|WS_VISIBLE|WS_VSCROLL|LBS_DISABLENOSCROLL|LBS_NOSEL;
dwStyle|=WS_CHILD|WS_VISIBLE|WS_VSCROLL|LBS_DISABLENOSCROLL|LBS_NOTIFY;
return CreateWindowEx(WS_EX_CLIENTEDGE, _T("listbox"),
caption.c_str(),
dwStyle,
rc.left, rc.top, rc.right, rc.bottom,
hParent,
reinterpret_cast<HMENU>(static_cast<INT_PTR>(id)),
hInst, 0);
}
check out this links for quite some good examples you are yearning for:
Windows API tutorial for the C programming language
FoosYerDoos ~ WinAPI Programming
Relisoft Software - Windows Api Tutorial
theForger's Win32 API Programming Tutorial
Win32 API Tutorials
If you go throught those tutorials you should be able to get along quite well.
This question already has answers here:
How to parse a string to an int in C++?
(17 answers)
Closed 7 years ago.
For the last 2 weeks i`ve been trying to make a program using windows.h library (for the simple use of GUI ). I managed to make a textbox that you can write in , but my problem is that you can only introduce data as char* . The programm is ment for my workers to be able to calculate some formulas easier & faster. How can i transform the char to an int , without having trouble with ASCII codes?
*I have also tried using strings. This is my actual code :
#if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif
#include <tchar.h>
#include <windows.h>
#include <string>
using namespace std;
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
HWND textstatic,texteditz1,texteditz2,textedit2,buttoncalculate,button2;
/* Make the class name into a global variable */
string inputZ1,inputZ2;
char *cinputZ1 = &inputZ1[0u];
TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");
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 = 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 = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* 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) COLOR_BACKGROUND;
/* 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*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
_T("Code::Blocks Template Windows App"), /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
500, /* The programs width */
500, /* 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_CREATE:
texteditz1 = CreateWindow ("EDIT","",
WS_VISIBLE | WS_CHILD,
60,50,45,14,
hwnd, (HMENU) 4,NULL,NULL);
texteditz2 = CreateWindow ("EDIT","",
WS_VISIBLE | WS_CHILD,
60,30,45,14,
hwnd, (HMENU) 5 ,NULL , NULL);
textstatic = CreateWindow ("STATIC",
"Z2=",
WS_VISIBLE | WS_CHILD,
30,50,30,15,
hwnd, NULL, NULL, NULL);
textstatic = CreateWindow ("STATIC",
"Z1=",
WS_VISIBLE | WS_CHILD,
30,30,30,15,
hwnd, NULL, NULL, NULL);
textstatic = CreateWindow ("STATIC",
"x1min=",
WS_VISIBLE | WS_CHILD,
30,70,50,15,
hwnd, NULL, NULL, NULL);
buttoncalculate = CreateWindow ("BUTTON",
"Calculate",
WS_VISIBLE | WS_CHILD,
150, 300, 70, 15,
hwnd, (HMENU) 1, NULL, NULL);
button2 = CreateWindow ("BUTTON","apasa",
WS_VISIBLE | WS_CHILD,
300, 300, 70, 15,
hwnd, (HMENU) 2, NULL, NULL);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case 1:
{
int text=0 ,text2=0 ;
text=GetWindowText(texteditz1,inputZ1,5);
text2=GetWindowText(texteditz2,inputZ2,5);
::MessageBox(hwnd, inputZ1, "Button",MB_OK);
::MessageBox(hwnd, inputZ2, "Text2",MB_OK);
}
break;
case 2:
::MessageBox (hwnd, "251", "button",NULL);
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;
}
you can use atoi() get int from a char*,
and _wtoi() get int from a wchar_t*.
so uauslly use _ttoi(),it will replacesed atoi or _wtoi.
int a = _ttoi("123");
and you need add stdlib.h
i tried to make the progress bar in c++ and it successfully worked with setting the position but when i tried to make it marquee i always get errors
#include <windows.h>
#include <commctrl.h>
#include <tchar.h>
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
HWND hWndButton;
HWND hEdit;
HWND hProgress;
char finalName[25];
char name[10];
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nCmdShow){
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASS wincl; /* Data structure for the windowclass */
ZeroMemory(&wincl, sizeof(WNDCLASS));
/* The Window structure */
wincl.hInstance = hInst;
wincl.lpszClassName = "Window Class";
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClass (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindow (
"Window Class", /* Classname */
("Code::Blocks Template Windows App"), /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
433, /* Windows decides the position */
134, /* where the window ends up on the screen */
500, /* The programs width */
500, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hInst, /* 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);
UpdateWindow(hwnd);
}
return 1;
}
/* 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_DESTROY:
PostQuitMessage (wParam); /* send a WM_QUIT to the message queue */
exit(1);
break;
case WM_CREATE:
UpdateWindow(hwnd);
hWndButton = CreateWindow("BUTTON", "Press Me!", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 0, 25, 100, 25, hwnd, (HMENU)1, NULL, NULL);
hEdit = CreateWindow("EDIT", "Write your name!", WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_AUTOVSCROLL|ES_AUTOHSCROLL, 0, 0, 200, 25, hwnd, (HMENU)2, NULL, NULL);
hProgress = CreateWindow(PROGRESS_CLASS, NULL, WS_CHILD|WS_VISIBLE|PBS_MARQUEE, 0, 100, 500, 20, hwnd, (HMENU)3, NULL, NULL);
SendMessage(hProgress, PBM_SETMARQUEE, 1, 1000);
UpdateWindow(hwnd);
break;
case WM_COMMAND:
if(wParam == 1){
GetWindowText(hEdit, _T(name), 10);
strcpy(finalName, "Hello, ");
strcat(finalName, name);
MessageBox(hwnd, (LPCSTR)finalName, "Your Name", MB_OK|MB_ICONINFORMATION);
}
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
}
saying that PBS_MARQUEE and PBM_SETMARQUEE were not defined in that scope though i included the commctrl.h header file, what is the problem??
The marquee mode was new for Windows XP, so you must define NTDDI_VERSION to be at least NTDDI_WINXP to include those constants. See Using the Windows Headers for more information.
I'm trying to create a program that suspends and resumes processes, it creates a listbox with text strings of all the running processes on the system, but when I click the suspend button to suspend a process I try to send WM_GETITEMDATA for the currently selected item in the listbox but the value returns 0. I expected the return value to be a string with the text of the lParam of LB_ADDSTRING.
I think this has something to do with the scope of the function I use LB_ADDSTRING in because when I use LB_GETITEMDATA right after LB_ADDSTRING it properly returns the value of the lParam of LB_ADDSTRING. Since I am unsure of where my error lies I'm adding the full source code to the bottom of my question. Here is the function I use to add strings to the listbox:
void RefreshList()
{
SendMessage (hlist, LB_RESETCONTENT, 0, 0);
HANDLE hSnapShot3 = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
PROCESSENTRY32 pEntry3;
pEntry3.dwSize = sizeof (pEntry3);
BOOL hRes3 = Process32First(hSnapShot3, &pEntry3);
int listitem = 0;
while (hRes3)
{
SendMessage (hlist, LB_ADDSTRING, 0, (LPARAM)pEntry3.szExeFile);
SendMessage (hlist, LB_SETITEMDATA, listitem, (LPARAM)pEntry3.szExeFile);
SendMessage(hlist, LB_GETITEMDATA, listitem, NULL);
MessageBox(0,0,0,0);
listitem++;
hRes3 = Process32Next(hSnapShot3, &pEntry3);
}
CloseHandle(hSnapShot3);
}
Here is the part of the windows procedure where I catch clicks to my context menu and try to send the message LB_GETITEMDATA:
case WM_COMMAND:
if (HIWORD(wParam) == 0 && LOWORD(wParam) == 1)
{
selection = SendMessage(hlist, LB_GETCURSEL, 0, 0);
LRESULT selectionname = SendMessage(hlist, LB_GETITEMDATA, selection, NULL);
}
here is the full code
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <process.h>
#include <Tlhelp32.h>
#include <winbase.h>
#include <string.h>
#include <stdio.h>
#include <windowsx.h>
#define list1 1
#define button1 2
int selection;
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ProcessListProc (HWND, UINT, WPARAM, LPARAM);
char szClassName[ ] = "mainwindowclass";
HWND hlist;
HWND hwnd;
void RefreshList()
{
SendMessage (hlist, LB_RESETCONTENT, 0, 0);
HANDLE hSnapShot3 = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
PROCESSENTRY32 pEntry3;
pEntry3.dwSize = sizeof (pEntry3);
BOOL hRes3 = Process32First(hSnapShot3, &pEntry3);
int listitem = 0;
while (hRes3)
{
SendMessage (hlist, LB_ADDSTRING, 0, (LPARAM)pEntry3.szExeFile);
SendMessage (hlist, LB_SETITEMDATA, listitem, (LPARAM)pEntry3.szExeFile);
SendMessage(hlist, LB_GETITEMDATA, listitem, NULL);
MessageBox(0,0,0,0);
listitem++;
hRes3 = Process32Next(hSnapShot3, &pEntry3);
}
CloseHandle(hSnapShot3);
}
int SuspendProcess(TCHAR processname)
{
int doublePID = 0;
DWORD pidtoacton;
DWORD Result;
HANDLE hSnapShot3 = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
PROCESSENTRY32 pEntry3;
pEntry3.dwSize = sizeof (pEntry3);
BOOL hRes3 = Process32First(hSnapShot3, &pEntry3);
while (hRes3)
{
if (processname == pEntry3.szExeFile);
{
if (doublePID != 0)
{
MessageBox (NULL, "2 processes of the same type detected, support not yet implimented!", NULL, MB_OK);
}
pidtoacton = pEntry3.th32ProcessID;
doublePID++;
}
hRes3 = Process32Next(hSnapShot3, &pEntry3);
}
HANDLE tsnap = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, 0);
THREADENTRY32 tentry;
tentry.dwSize = sizeof (tentry);
BOOL CRec = Thread32First(tsnap, &tentry);
while (CRec)
{
if (tentry.th32OwnerProcessID == pidtoacton)
{
HANDLE handletoacton = OpenThread(2, 0, tentry.th32ThreadID);
Result = SuspendThread(handletoacton);
if (Result == -1)
{
MessageBox (NULL, "An unknown error has occured when attempting to suspend a thread in the process", NULL, MB_OK);
}
}
CRec = Thread32Next(tsnap, &tentry);
}
CloseHandle(tsnap);
}
MSG messages;
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
/* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
MSG messages2;
/* The Window structure */
wincl.hInstance = 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 = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* 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) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* Register the window class, and if it fails quit the program */
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Process suspender", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
350, /* The programs width */
650, /* 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 */
);
hlist = CreateWindowEx (0,TEXT("listbox"),NULL,WS_CHILD|WS_VISIBLE|LBS_NOTIFY|LBS_STANDARD|LBS_HASSTRINGS,10,15,320,500,hwnd,(HMENU)list1,NULL,NULL);
RefreshList();
HWND hWndButton = CreateWindowEx(NULL,
TEXT("button"),
TEXT("refresh"),
WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
130,
535,
80,
30,
hwnd,
(HMENU)button1,
NULL,
NULL);
/* 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_CONTEXTMENU:
{
if ((HWND)wParam == hlist)
{
INPUT clickin;
clickin.type = 0;
clickin.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
clickin.mi.dx = 0;
clickin.mi.dy = 0;
clickin.mi.mouseData = 0;
clickin.mi.time = 0;
clickin.mi.dwExtraInfo = 0;
SendInput(1,&clickin,sizeof(clickin));
clickin.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1,&clickin,sizeof(clickin));
GetMessage (&messages, NULL, 0, 0);
TranslateMessage(&messages);
DispatchMessage(&messages);
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
HMENU rightclickmenu = CreatePopupMenu();
InsertMenu(rightclickmenu, 1, MF_BYCOMMAND | MF_STRING | MF_ENABLED, 1, "Suspend");
InsertMenu(rightclickmenu, 0, MF_BYCOMMAND | MF_STRING | MF_ENABLED, 0, "Resume");
TrackPopupMenu(rightclickmenu, TPM_TOPALIGN | TPM_LEFTALIGN, xPos, yPos, 0, hwnd, NULL);
}
break;
}
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
case WM_COMMAND:
if (HIWORD(wParam) == 0 && LOWORD(wParam) == 1)
{
selection = SendMessage(hlist, LB_GETCURSEL, 0, 0);
LRESULT selectionname = SendMessage(hlist, LB_GETITEMDATA, selection, NULL);
}
switch (wParam)
{
case button1:
RefreshList();
break;
}
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
As #JonathanPotter mentions in his comment, you need to use LB_GETTEXT to retrieve the text of an item.
If you were going to use LB_SETITEMDATA to store, say, the process-id for each item, it is good practice to always use the index returned by the LB_ADDSTRING and not assume that the index will always increment by one, this will work for sorted and unsorted list boxes:
listitem = SendMessage(hlist, LB_ADDSTRING, 0, (LPARAM)pEntry3.szExeFile);
SendMessage(hlist, LB_SETITEMDATA, listitem, (LPARAM)pEntry3.th32ProcessID);
Hello I'm attempting to learn how to create Windows Apps using the WIN32 API. To this end I am going through The Forgers Tutorial on the subject. I am stuck at trying to get my first dialog box to show up when my menu item is clicked. I have checked out the MSDN site and looked at the documentation on all relevant functions in my code and everything APPEARS correct TO ME. But, of course, I don't know because I'm just learning I wonder if anyone can point out my error or perhaps point me in the direction of what I may be missing in the documentation. I'm sure that it's something really dumb (as it always is with these things)
at any rate here's my little script. Hopefully any of you can help. Thanks
#include <windows.h>
#include "resource.h"
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
/* Make the class name into a global variable */
char szClassName[ ] = "WindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
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 = 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 = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* 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*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Windows App", /* 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, nFunsterStil);
/* 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_CREATE:
{
HMENU hMenu, hSubMenu, hOtherMenu, hOtherSubMenu;
hMenu = CreateMenu();
hSubMenu = CreatePopupMenu();
hOtherMenu = CreateMenu();
hOtherSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "E&xit");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&File");
AppendMenu(hSubMenu, MF_STRING, ID_STUFF, "S&tuff");
AppendMenu(hOtherSubMenu, MF_STRING,ID_OTHER_SUB, "O&ther");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hOtherSubMenu, "&Other");
SetMenu(hwnd, hMenu);
//SetMenu(hwnd, hOtherMenu);
}
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd, "this is my program", "program box", 0);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_STUFF:
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_ABOUT), hwnd, AboutDlgProc);
break;
case ID_FILE_EXIT:
PostQuitMessage(0);
break;
}
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
switch(message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
EndDialog(hwnd, IDOK);
break;
case IDCANCEL:
EndDialog(hwnd, IDCANCEL);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
this is the .rc
#include "resource.h"
#include <windows.h>
IDR_MYMENU MENU
BEGIN
POPUP "F&ile"
BEGIN
MENUITEM "E&xit", ID_FILE_EXIT
MENUITEM "stuff I like", ID_STUFF
END
END
IDD_ABOUT DIALOG DISCARDABLE 0,0,239,66
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About Box"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "&ok", IDOK, 174,18,50,14
PUSHBUTTON "&Cancel", IDCANCEL, 174,18,50,14
GROUPBOX "About this program...",IDC_STATIC,7,7,225,52
CTEXT "This is a Modular Database program", IDC_STATIC, 16,18,144,33
END
and this is the header for the .rc
#define IDR_MYMENU 101
#define ID_FILE_EXIT 4001
#define ID_STUFF 4002
#define IDC_STATIC -1
#define IDD_ABOUT 102
#define ID_OTHER_SUB 4003
P.S. I am a first time poster to any forum at all so I apologize if I didn't get the code in clearly please just let me know Thanks again!
i think you didn't add resource.h and recource.rc to your project.
if you don't add them your project will compile but dialog-box will not shown.
I compiled your code and it worked fine.
i use mingw4.7 and devc++ IDE.