Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Программирование в С++ стиле

11K
24 апреля 2005 года
Alex_beginner
1 / / 24.04.2005
Здравствуйте уважаемые участники форума!
Заранее прошу прощения за то,что это скорее вопрос чем тема для обсуждения.
Я только начинаю знакомиться с Win32 API и программированием под Windows,естественно появляется много вопросов.
Почти везде в документации(Петцольд,Шилдт,MSDN и т.д.) приводятся примеры программирования на Win32 API в "C" стиле(структурном),а посему вопрос :
это единственный вариант или нет,а если нет,то можно ли (и самое главное как)писать на С++ используя Win32 API,но не используя VCL,MFC,ATL и т.п.,то есть используя нужные типы данных и функции из Win32 API,а объекты и логику их работы описывать самостоятельно(то есть в объектно-ориентированном,а не в структурном стиле).Единственный вариант подобного рода я встретил в документации к Borland C++ 3.1 и Borland C++ 5.02 (листинг прилагается),но все попытки откомпилировать и запустить этот код в Borland C++ Builder 6.0 и Visual Studio .Net 2003 окончились неудачей.Буду благодарен если порекомендуете какие-нибудь ссылки(в случае положительного ответа на заданный вопрос) и/или литературу.Я хочу для себя сделать вывод стоит ли тратить на это время(если это вообще возможно) или сосредоточиться на изучении VC++,Borland C++ Builder и т.п.
Заранее благодарен за любой отклик по этой теме.

// Borland C++ - (C) Copyright 1991, 1992 by Borland International
//
// Windows HELLO WORLD - C++ Version

#define STRICT
#include <windows.h>
#include <stdlib.h>
#include <string.h>

LRESULT CALLBACK _export WndProc( HWND hWnd, UINT iMessage,
WPARAM wParam, LPARAM lParam );

class Main
{
public:
static HINSTANCE hInstance;
static HINSTANCE hPrevInstance;
static int nCmdShow;
static int MessageLoop( void );
};

class Window
{
protected:
HWND hWnd;
public:
HWND GetHandle( void ) { return hWnd; }
BOOL Show( int nCmdShow ) { return ShowWindow( hWnd, nCmdShow ); }
void Update( void ) { UpdateWindow( hWnd ); }
virtual long WndProc( UINT iMessage, WPARAM wParam, LPARAM lParam ) = 0;
};

class MainWindow : public Window
{
private:
static char szClassName[14];
static void FAR PASCAL LineFunc( int X, int Y, LPSTR lpData );
public:
static void Register( void )
{
WNDCLASS wndclass; // Structure used to register Windows class.

wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = ::WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = sizeof( MainWindow * );
wndclass.hInstance = Main::hInstance;
wndclass.hIcon = LoadIcon( Main::hInstance, "whello" );
wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
wndclass.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szClassName;

if ( ! RegisterClass( &wndclass ) )
exit( FALSE );
}

MainWindow( void )
{
hWnd = CreateWindow( szClassName,
szClassName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
Main::hInstance,
(LPSTR) this );
if ( ! hWnd )
exit( FALSE );

Show( Main::nCmdShow );
Update();
}
long WndProc( UINT iMessage, WPARAM wParam, LPARAM lParam );

void Paint( void );
struct LINEFUNCDATA
{
HDC hDC;
char FAR *LineMessage;
int MessageLength;
LINEFUNCDATA( char *Message )
{
hDC = 0;
MessageLength = strlen( Message );
LineMessage = new far char [MessageLength+1];
lstrcpy( LineMessage, Message );
};
~LINEFUNCDATA( void ) { delete LineMessage; }
};
};

HINSTANCE Main::hInstance = 0;
HINSTANCE Main::hPrevInstance = 0;
int Main::nCmdShow = 0;

int Main::MessageLoop( void )
{
MSG msg;

while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return msg.wParam;
}

char MainWindow::szClassName[] = "Hello, World!";

void MainWindow::Paint( void )
{
PAINTSTRUCT ps;
RECT rect;
FARPROC lpLineFunc;
LINEFUNCDATA LineFuncData( "Borland C++ welcomes you to the Wonderful World of Windows Programming!" );

lpLineFunc = MakeProcInstance( (FARPROC) MainWindow::LineFunc, (HINSTANCE)Main::hInstance );
BeginPaint( hWnd, &ps );
GetClientRect( hWnd, (LPRECT) &rect );
LineFuncData.hDC = ps.hdc;
SetTextAlign( ps.hdc, TA_BOTTOM );
LineDDA( 0, 0, 0,
rect.bottom / 2, (LINEDDAPROC)lpLineFunc, (LPARAM) &LineFuncData );
EndPaint( hWnd, &ps );
FreeProcInstance( lpLineFunc );
}

void FAR PASCAL _export MainWindow::LineFunc( int X, int Y, LPSTR lpData )
{
LINEFUNCDATA FAR * lpLineFuncData = (LINEFUNCDATA FAR *) lpData;
TextOut( lpLineFuncData->hDC, X, Y,
lpLineFuncData->LineMessage, lpLineFuncData->MessageLength );
}

long MainWindow::WndProc( UINT iMessage, WPARAM wParam, LPARAM lParam )
{
switch (iMessage)
{
case WM_CREATE:
break;
case WM_PAINT:
Paint();
break;
case WM_DESTROY:
PostQuitMessage( 0 );
break;
default:
return DefWindowProc( hWnd, iMessage, wParam, lParam );
}
return 0;
}

#if defined(__SMALL__) || defined(__MEDIUM__)
inline Window *GetPointer( HWND hWnd )
{
return (Window *) GetWindowWord( hWnd, 0 );
}
inline void SetPointer( HWND hWnd, Window *pWindow )
{
SetWindowWord( hWnd, 0, (WORD) pWindow );
}

#elif defined(__LARGE__) || defined(__COMPACT__)
inline Window *GetPointer( HWND hWnd )
{
return (Window *) GetWindowLong( hWnd, 0 );
}
inline void SetPointer( HWND hWnd, Window *pWindow )
{
SetWindowLong( hWnd, 0, (LONG) pWindow );
}

#else
#error Choose another memory model!
#endif

LRESULT CALLBACK _export WndProc( HWND hWnd, UINT iMessage, WPARAM wParam,
LPARAM lParam )
{
Window *pWindow = GetPointer( hWnd );

if ( pWindow == 0 )
{
if ( iMessage == WM_CREATE )
{
LPCREATESTRUCT lpcs;

lpcs = (LPCREATESTRUCT) lParam;
pWindow = (Window *) lpcs->lpCreateParams;

SetPointer( hWnd, pWindow );
return pWindow->WndProc( iMessage, wParam, lParam );
}
else
return DefWindowProc( hWnd, iMessage, wParam, lParam );
}
else
return pWindow->WndProc( iMessage, wParam, lParam );
}


#pragma argsused

#pragma option -w-aus

int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine,
int nCmdShow )
{
Main::hInstance = hInstance;
Main::hPrevInstance = hPrevInstance;
Main::nCmdShow = nCmdShow;

if ( ! Main::hPrevInstance ) {
MainWindow::Register();
}

MainWindow MainWnd;

return Main::MessageLoop();
}
7.8K
25 апреля 2005 года
EcliptoR
19 / / 17.01.2005
Судя по всему код этот еще для Win16. Да и Borland C++ не лучший компилятор. Забей на это и юзай MFC - это программирование под windows в С++ стиле, если тебе надо скорость и малый размер. Кроме того можешь взглянуть на NET - лично мне понравилось. А на Borland забей - они никогда нормальных компиляторов делать не умели. Microsoft и Intel - rulezzz!!! Borland - suxx && mustdie!!! так вот...
3
25 апреля 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by Alex_beginner

это единственный вариант или нет,а если нет,то можно ли (и самое главное как)писать на С++ используя Win32 API,но не используя VCL,MFC,ATL и т.п.,то есть используя нужные типы данных и функции из Win32 API,а объекты и логику их работы описывать самостоятельно(то есть в объектно-ориентированном,а не в структурном стиле).


Можно, но сначала ответь на вопрос: зачем изобретать велосипед? Тем более, если слабо знаком с велосипедостроением...

Цитата:
Originally posted by EcliptoR
Забей на это и юзай MFC - это программирование под windows в С++ стиле, если тебе надо скорость и малый размер.


MFC - это программирование под windows в ПЛОХОМ С++ стиле.
Для более-менее хорошего стиля юзай WTL.

7.8K
27 апреля 2005 года
EcliptoR
19 / / 17.01.2005
По крйней мере другой более-менее нормальной альтернативы MFC на рынке нет. WTL это замечательно, но это тогда станет хорошо, когда до релиза доберется. Та же в пример хорошего стиля можно привести QT. VCL тоже в принципе ничего, да вот только тяжелое наследие Delphi несколько угнетает. Самая прогрессивная MS-технология dotNET тоже может стать отличным выбором. Правда не на C++ а на C#.
3
27 апреля 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by EcliptoR
По крйней мере другой более-менее нормальной альтернативы MFC на рынке нет.


Я ж говорю есть - WTL.

Цитата:
Originally posted by EcliptoR
WTL это замечательно, но это тогда станет хорошо, когда до релиза доберется.


а вот что ты этим хотел сказать непонятно.

Цитата:
Originally posted by EcliptoR
Та же в пример хорошего стиля можно привести QT.


Имеет смысл только при создании кросс- и мульти- платформенных приложений

Цитата:
Originally posted by EcliptoR
VCL тоже в принципе ничего, да вот только тяжелое наследие Delphi несколько угнетает.


VCL - полная лажа.

Цитата:
Originally posted by EcliptoR

Самая прогрессивная MS-технология dotNET тоже может стать отличным выбором. Правда не на C++ а на C#.


.NET это из другой оперы...
да и необязательно C#...

7.8K
28 апреля 2005 года
EcliptoR
19 / / 17.01.2005
А хотел я этим сказать, что когда это дойдет до финального релиза, когда будет нормальная документация, хотя бы хэндбук приличный (А то я качнул эти 600кб и не знаю что с ними делать. Кстати размер в 600 кб - это круто) Тогда и будем юзать. А вообще вещь весьма прогрессивная.
QT может и под винду хорошо использоваться, благо в VC интегрируется. Насчет NET - мне кажется, что уже года через три приличная часть программ будет работать на NET. И не только под виндами. У NET хорошие преспективы. Microsoft наконец то повернулась к народу лицом и начала делать нормальный варез для людей.
7.8K
28 апреля 2005 года
EcliptoR
19 / / 17.01.2005
Поправка: WTL оказывается разработала Microsoft!
Могут же если захотят. Я поглядел - штука хорошая.
Есть ли толковая книженция (можно на англ.) по ее использованию. Заранее благодарен.
3
28 апреля 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by EcliptoR
А хотел я этим сказать, что когда это дойдет до финального релиза, когда будет нормальная документация, хотя бы хэндбук приличный (А то я качнул эти 600кб и не знаю что с ними делать. Кстати размер в 600 кб - это круто) Тогда и будем юзать.



Не поверишь, мы используем WTL уже в течении трех лет в коммерческих проектах.
Информации по WTL полно. Он и сам по себе очень информативен: не понятно что-то открываешь соотв. его файл и смотришь код.

7.8K
12 мая 2005 года
EcliptoR
19 / / 17.01.2005
Кстати если тебе еще интересно: исходник твой я скомпилил.

Вот испр. версия

// Borland C++ - (C) Copyright 1991, 1992 by Borland International
//
// Windows HELLO WORLD - C++ Version

#include <windows.h>
#include <stdlib.h>
#include <string.h>

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage,
WPARAM wParam, LPARAM lParam);

class Main {
public:
static HINSTANCE hInstance;
static HINSTANCE hPrevInstance;
static int nCmdShow;
static int MessageLoop(void);
};


class Window {
protected:
HWND hWnd;
public:
HWND GetHandle(void) {
return hWnd;
}
BOOL Show(int nCmdShow) {
return ShowWindow(hWnd, nCmdShow);
}
void Update(void) {
UpdateWindow(hWnd);
}
virtual long WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) = 0;
};

class MainWindow : public Window {
private:
static char szClassName[14];
static void FAR PASCAL LineFunc(int X, int Y, LPSTR lpData);

public:
static void Register(void) {

WNDCLASS wndclass; // Structure used to register Windows class.

wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = ::WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = sizeof(MainWindow *);
wndclass.hInstance = Main::hInstance;
wndclass.hIcon = LoadIcon(Main::hInstance, "whello");
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szClassName;

if(!RegisterClass(&wndclass)) exit(FALSE);
}

MainWindow(void) {
hWnd = CreateWindow( szClassName,
szClassName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
Main::hInstance,
(LPSTR)this);

if (!hWnd) exit(FALSE);

Show(Main::nCmdShow);
Update();
}

long WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam);

void Paint(void);
struct LINEFUNCDATA
{
HDC hDC;
char FAR *LineMessage;
int MessageLength;
LINEFUNCDATA(char *Message) {
hDC = 0;
MessageLength = strlen(Message);
LineMessage = new char [MessageLength+1];
lstrcpy(LineMessage, Message);
};
~LINEFUNCDATA(void) {
delete LineMessage;
}
};
};

HINSTANCE Main::hInstance = 0;
HINSTANCE Main::hPrevInstance = 0;
int Main::nCmdShow = 0;

int Main::MessageLoop(void) {
MSG msg;

while( GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
}

char MainWindow::szClassName[] = "Hello, World!";

void MainWindow::Paint(void) {
PAINTSTRUCT ps;
RECT rect;
FARPROC lpLineFunc;
LINEFUNCDATA LineFuncData("Corrected app!");
lpLineFunc = MakeProcInstance( (FARPROC) MainWindow::LineFunc, (HINSTANCE)Main::hInstance );
BeginPaint(hWnd, &ps);
GetClientRect(hWnd, (LPRECT) &rect);
LineFuncData.hDC = ps.hdc;
SetTextAlign(ps.hdc, TA_BOTTOM);
LineDDA(0, 0, 0,
rect.bottom / 2, (LINEDDAPROC)lpLineFunc, (LPARAM) &LineFuncData);
EndPaint(hWnd, &ps);
FreeProcInstance(lpLineFunc);
};

void FAR PASCAL MainWindow::LineFunc(int X, int Y, LPSTR lpData) {
LINEFUNCDATA FAR * lpLineFuncData = (LINEFUNCDATA FAR *) lpData;
TextOut( lpLineFuncData->hDC, X, Y,
lpLineFuncData->LineMessage, lpLineFuncData->MessageLength);
}

long MainWindow::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
switch (iMessage) {
case WM_CREATE:
break;
case WM_PAINT:
Paint();
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, iMessage, wParam, lParam);
}
return 0;
}

inline Window *GetPointer( HWND hWnd ) {
return (Window *) GetWindowLong(hWnd, 0);
}
inline void SetPointer(HWND hWnd, Window *pWindow) {
SetWindowLong(hWnd, 0, (LONG) pWindow);
}


LRESULT CALLBACK WndProc( HWND hWnd, UINT iMessage, WPARAM wParam,
LPARAM lParam ) {
Window *pWindow = GetPointer(hWnd);

if (pWindow == 0) {
if (iMessage == WM_CREATE) {
LPCREATESTRUCT lpcs;

lpcs = (LPCREATESTRUCT) lParam;
pWindow = (Window *) lpcs->lpCreateParams;

SetPointer(hWnd, pWindow);
return pWindow->WndProc(iMessage, wParam, lParam);
}
else
return DefWindowProc(hWnd, iMessage, wParam, lParam);
}
else
return pWindow->WndProc(iMessage, wParam, lParam);
}


int PASCAL WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow) {

Main::hInstance = hInstance;
Main::hPrevInstance = hPrevInstance;
Main::nCmdShow = nCmdShow;

if (!Main::hPrevInstance) {
MainWindow::Register();
}

MainWindow MainWnd;

return Main::MessageLoop();
}

Сорри за такой постинг сорца.
Metrowerks CodeWarrior компилит на ура.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог