Page 1 of 1

Win32 API control expansion?

Posted: Tue Dec 07, 2010 3:42 am
by Kyosaur
Hello, im midway through my first win32 program and started wondering about something. In my application i have an edit control and a button control. I hate having to get the width/height perfect for these two controls, and also hate that when you expand the window they do not expand with it, is there any way to achieve this? I tried searching before making this post, but found nothing at all really. Its kind of a shame that when the application is full screen (disabled for now) the controls dont fill the window :'(.

Here's my project so far.

Code: Select all

/*
    Kyoshiro's SA-MP Converter is an application which converts map files
	into a format suitible for San Andreas Multiplayer.
    Copyright (C) 2010 Kyoshiro aka Kyosaur.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <windows.h>
#include <string.h>
#include <tchar.h>

using namespace std;

//type def incase i want to use it
typedef const char cchar;

//window dimensions
#define WINDOW_WIDTH 300
#define WINDOW_HEIGHT 300

//function overloading for itos
inline void itos(char str[], float number) { sprintf(str, "%f", number); }
inline void itos(char str[], int number) { sprintf(str, "%d", number); }

//macro to just shorten the code...
#define SPECIFIER_CHECK(p) if(!str.compare(pos,(end-pos)+1,"{" #p "}")){ itos(tmp,p); str.replace(pos,(end-pos)+1,tmp); continue;}

//enum for our menu's
enum 
{
	E_MENU_MENUBAR,
	E_MENU_FILE,
	E_MENU_OPEN,
	E_MENU_SAVE,
	E_MENU_QUIT,
	E_MENU_OBJECTS,
	E_MENU_VEHICLES,
	E_MENU_FO_CREATEOBJECT,
	E_MENU_FO_INCOGNITO,
	E_MENU_FO_XSTREAMER,
	E_MENU_FO_XOBJECTS,
	E_MENU_FO_CUSTOM,
	E_MENU_FI_MTADM,
	E_MENU_FI_MTARACE,
	E_MENU_FI_MTA1,
	E_EVENT_TEXTBOX,
	E_EVENT_CONVERT
};

//Object formats for converting
string g_Formats[] =
{
	"CreateObject({Model},{X},{Y},{Z},{RX},{RY},{RZ});",
	"CreateDynamicObject({Model},{X},{Y},{Z},{RY},{RY},{RZ},{Dimension},{Interior},-1,{DD});"
};

//Our class for converting 

class Convert
{
private:
	int
		Model,
		Interior,
		Dimension;
	float
		X,
		Y,
		Z,
		RX,
		RY,
		RZ,
		DD;
public:
	Convert();

	void ParseInput(cchar,cchar);
	string FormatOutput(string);
};

//Convert constructor - set all values to NULL 
Convert::Convert()
{
	Model = Interior = Dimension = X = Y = Z = RX = RY = RZ = DD = NULL;
}

//Yucky FormatOutput for converting
string Convert::FormatOutput(string format)
{
	string 
		str = format;
	
	size_t
		pos = NULL,
		end = NULL;

	char 
		tmp[11];

	//search the string for "{"
	while((pos = str.find("{",pos+1)) != string::npos)
	{
		//while there's a "{", search for a "}"
		if((end = str.find("}",pos)) != string::npos)
		{
			/*
				if we found a closing brace we need
				to check if the content between matches
				one of our specifiers. If it does replace
				that part of the string with the correct
				value.

				I use a macro to cut down the code drastically.
			*/

			SPECIFIER_CHECK(Model);
			SPECIFIER_CHECK(X);
			SPECIFIER_CHECK(Y);
			SPECIFIER_CHECK(Z);
			SPECIFIER_CHECK(RX);
			SPECIFIER_CHECK(RY);
			SPECIFIER_CHECK(RZ);
			SPECIFIER_CHECK(Interior);
			SPECIFIER_CHECK(Dimension);
			SPECIFIER_CHECK(DD);
		}
	}
	return str;
}

//function prototpe for the Window procedure (aka a "forward")
LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);

//Heart of the code (main)
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	//Creating our WNDCLASS and MSG structures.
	MSG msg				= {0};
	WNDCLASS wc			= {0};

	//Fill out information for out window
	wc.lpszClassName	= _T("Kyoshiro's SA-MP Converter!");
	wc.lpfnWndProc		= WindowProc;
	wc.hInstance		= hInstance;
	wc.hbrBackground	= GetSysColorBrush(COLOR_3DFACE);
	wc.hCursor			= LoadCursor(hInstance,IDC_ARROW);

	//register our window structure
	RegisterClass(&wc);

	//Create the window + error checking if it fails
	if(!CreateWindow(wc.lpszClassName,_T("Kyoshiro's SA-MP Converter!"),WS_VISIBLE | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX,100,100,WINDOW_WIDTH,WINDOW_HEIGHT,NULL,NULL,hInstance,NULL))
	{
		MessageBox(NULL,_T("There was a problem with window creation!"),_T("Error"),NULL);
		return 1;
	}

	
	//Here we get messages from windows, translate them,
	//and then send them to the window procedure.
	
	while(GetMessage(&msg,NULL,NULL,NULL))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return (int) msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	switch(Msg)
	{
		case WM_CREATE:
		{

			//Creating the menus
			HMENU hMenuBar		= CreateMenu();
			HMENU hFile			= CreateMenu();
			HMENU hOptions		= CreateMenu();
			HMENU hVehFormat	= CreateMenu();
			HMENU hObjFormat	= CreateMenu();

			//Appending itemps to the hFile menu
			AppendMenu(hFile, MF_STRING, E_MENU_OPEN, _T("Open Map"));
			AppendMenu(hFile, MF_STRING, E_MENU_SAVE, _T("Save Map"));
			AppendMenu(hFile, MF_SEPARATOR, NULL, NULL);
			AppendMenu(hFile, MF_STRING, E_MENU_QUIT, _T("Quit"));

			//Appending items to hObjFormat 
			AppendMenu(hObjFormat, MF_STRING, E_MENU_FO_CREATEOBJECT, _T("CreateObject"));
			AppendMenu(hObjFormat, MF_STRING, E_MENU_FO_INCOGNITO, _T("Streamer plugin (incognito)"));
			AppendMenu(hObjFormat, MF_STRING, E_MENU_FO_XSTREAMER, _T("xStreamer plugin"));
			AppendMenu(hObjFormat, MF_STRING, E_MENU_FO_XOBJECTS, _T("xObjects"));
			AppendMenu(hObjFormat, MF_SEPARATOR, NULL, NULL);
			AppendMenu(hObjFormat, MF_STRING, E_MENU_FO_CUSTOM, _T("Custom format"));

			//Append the hObjFormat menu to hOptions
			AppendMenu(hOptions, MF_POPUP, NULL, _T("Input"));
			AppendMenu(hOptions, MF_POPUP, (UINT_PTR) hObjFormat, _T("Output"));

			//Append hFile and hOptions to the hMenuBar
			AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR) hFile, _T("File"));
			AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR) hOptions, _T("Options"));

			//Apply the menu to our winodw
			SetMenu(hWnd,hMenuBar);

			//crap for testing custom output (temp)
			Convert convert;

			wstring test;
			string tmp = convert.FormatOutput(g_Formats[1]);

			test.assign(tmp.begin(),tmp.end());

			//create our textbox and convert buttons!
			CreateWindow(_T("edit"),test.c_str(),WS_VISIBLE|WS_CHILD|WS_BORDER|ES_MULTILINE|ES_WANTRETURN|ES_AUTOHSCROLL|ES_AUTOVSCROLL,0,0,WINDOW_WIDTH-5,200,hWnd,(HMENU) E_EVENT_TEXTBOX,NULL,NULL);
			CreateWindow(_T("button"),_T("Convert!"), WS_CHILD | WS_VISIBLE | WS_BORDER,0,200,WINDOW_WIDTH-2,49,hWnd,(HMENU) E_EVENT_CONVERT,NULL,NULL);
			return 1;
		}

		case WM_COMMAND:
		{
			switch(LOWORD(wParam))
			{
				case E_MENU_QUIT:
				{
					PostQuitMessage(0);
				}
				case E_EVENT_TEXTBOX:
				{
					if(HIWORD(wParam) == EN_CHANGE)
					{
						//change save var and give a quit warning
					}
					return 0;
				}
			}
			return 0;
		}

		case WM_DESTROY:
		{
			PostQuitMessage(0);
			return 0;
		}
	}

	return DefWindowProc(hWnd,Msg,wParam,lParam);
}

If you have a way to improve my code, feel free to post it as well! Im still getting used to c++ so im sure there are better ways of doing something.

Re: Win32 API control expansion?

Posted: Wed Dec 08, 2010 5:37 pm
by Kyosaur
Does anyone have an idea?

If not i also have another question :D. In my program i have a menu with a submenu attached to it so users can pick a format to convert with. My problem is that i cant show what is currently selected, how would i do that?

For example, in firefox go to view -> character encoding. How would i put a little check or dot in the menu like that?


Sorry, i tried searching for the answers its just these two questions are really hard to find lol.