08.10.2008, 14:38
общий
это ответ
Здравствуйте, Ustin7!
В приложении исправленная программа
Исправленные места помечены комментариями, начинающимися с //***liv***
Приложение:
//exmpl.cpp
#include "Functions.h"
#define ID_STATIC 2000
#define ID_BUTTON1 2001
#define ID_BUTTON2 2002
#define ID_BUTTON3 2003
#define ID_HELP 2004
LRESULT CALLBACK WndProc(HWND,UINT, WPARAM,LPARAM);
LRESULT CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
int CreateDlg (HWND);
HINSTANCE hInstance;
char szClass[] = "AppClass";
//***liv*** Буковка I в имени hInstance должна быть заглавной
INT WINAPI WinMain (HINSTANCE hInstance, HINSTANCE, PSTR, INT nCmdShow)
{ MSG msg; HWND hwnd; ::hInstance=hInstance;
if (!RegClass(WndProc,szClass,COLOR_DESKTOP)) return FALSE;
int wScreen=GetSystemMetrics(SM_CXSCREEN);
int hScreen=GetSystemMetrics(SM_CYSCREEN);
hwnd = CreateWindow(szClass, "Создание диалоговой панели", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0,0, wScreen/2, hScreen/2, 0,0, hInstance, NULL);
if (!hwnd) return FALSE;
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)
{ switch (msg)
{ case WM_CREATE:
{ CreateDlg(hwnd); return 0;}
case WM_DESTROY:
{ PostQuitMessage(0); return 0;}
} return DefWindowProc(hwnd, msg, wParam, lParam);
}
LRESULT CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ switch (msg)
{ case WM_COMMAND:
{ switch(LOWORD(wParam))
{ case IDOK:
case IDCANCEL:
{ EndDialog(hwnd, 0); //***liv*** Модальный диалог надо завершать!
return TRUE; }
} return FALSE;
}
} return FALSE;
}
int CreateDlg( HWND hwnd )
{ char const caption[ ]=" Изменение режима работы приложения";
char const stattxt[ ]="Сейчас следует:";
char const modeoff[ ]="завершить работу приложения";
char const modedat[ ]="перезагрузить данные";
char const modepsw[ ]="сменить имя пользователя";
//Выделяем блок памяти для записи шаблона
WORD *p, *pdlgtemplate;
pdlgtemplate=p=(PWORD)LocalAlloc(LPTR, 2000);
//Определяем среднюю ширину cxChar и высоту cyChar шрифта
int cxChar, cyChar;
{ TEXTMETRIC tm;
HDC hdc=GetDC(hwnd);
GetTextMetrics(hdc,&tm);
ReleaseDC(hwnd, hdc);
cxChar=tm.tmAveCharWidth+1;
cyChar=tm.tmHeight+tm.tmExternalLeading;
}
//Определяем диалоговые единицы ширины и высоты
DWORD dlgunit =GetDialogBaseUnits();
int dlgwunit=LOWORD(dlgunit), dlghunit=HIWORD(dlgunit);
//Пересчитываем габариты символов шрифта
cxChar=cxChar*4/dlgwunit;cyChar=cyChar*8/dlghunit;
int wDlg, hDlg, wItem, hItem, left, top;
//Записываем в шаблон данные панели
DWORD lStyle = DS_CENTER | DS_MODALFRAME | WS_POPUPWINDOW | WS_CAPTION;
wDlg=lstrlen(caption)*cxChar;
hDlg=cyChar*10;
DlgTemplate(p, lStyle, 7, 0, 0, wDlg, hDlg, (LPSTR)caption);
//Далее добавляем записи органов управления
//1
hItem=cyChar; top=left=hItem/2; hItem+=left; wItem=(wDlg-left-left);
lStyle = WS_CHILD | WS_VISIBLE | BS_GROUPBOX | WS_TABSTOP;
//***liv*** Класс органа управления должен задаваться числом, а не адресом строки!
//***liv*** Описаны в h-ке
DlgItemTemplate(p, lStyle, left, top, wItem, 4*hItem+left, ID_STATIC,
S_BUTTON,(LPSTR)stattxt);
//2
wItem=lstrlen(modeoff)*cxChar+10; top+=hItem;
lStyle = BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP;
DlgItemTemplate(p, lStyle, hItem, top, wItem, hItem, ID_BUTTON1,
S_BUTTON, (LPSTR)modeoff);//***liv*** аналогично
//3
wItem=lstrlen(modedat)*cxChar+10; top+=hItem;
lStyle = BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE;
DlgItemTemplate(p, lStyle, hItem, top, wItem, hItem, ID_BUTTON2,
S_BUTTON, (LPSTR)modedat);//***liv*** аналогично
//4
wItem=lstrlen(modepsw)*cxChar+10; top+=hItem;
lStyle = BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE;
DlgItemTemplate(p, lStyle, hItem, top, wItem, hItem, ID_BUTTON3,
S_BUTTON, (LPSTR)modepsw);//***liv*** аналогично
//5
wItem=(wDlg-left-left-hItem-hItem)/3; top+=hItem+hItem/2+left;
lStyle = BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP;
DlgItemTemplate(p, lStyle, left, top, wItem, hItem, IDOK,
S_BUTTON,(LPSTR)"Да");//***liv*** аналогично
//6
lStyle = BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP;
DlgItemTemplate(p, lStyle, left+wItem+hItem, top, wItem, hItem, IDCANCEL,
S_BUTTON,(LPSTR)"Oтмена");//***liv*** аналогично
//7
DlgItemTemplate(p, lStyle, left+wItem+hItem+wItem+hItem, top, wItem, hItem, ID_HELP,
S_BUTTON,(LPSTR)"Cправка");//***liv*** аналогично
//Создаем модальное диалоговое окно
DialogBoxIndirect(hInstance,(LPDLGTEMPLATE)pdlgtemplate, hwnd, (DLGPROC)DlgProc);
//Освобождаем занятый под шаблон блок памяти
LocalFree(LocalHandle(pdlgtemplate));
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Functions.cpp
#include "Functions.h"
BOOL RegClass (WNDPROC Proc, LPCTSTR szName, UINT brBackground)
{ WNDCLASS wc;
wc.style = 0;
wc.lpfnWndProc = Proc;
wc.cbClsExtra = wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground =(HBRUSH)(COLOR_WINDOW +1);
wc.lpszMenuName =(LPCTSTR)NULL;
wc.lpszClassName = szName;//***liv*** ошибочка в имени поля
return (RegisterClass (&wc) !=0);
}
LPWORD lpwAlign(LPWORD lpln)
{
ULONG ul=(ULONG)lpln;
ul+=3;
ul>>=2;
ul<<=2;
return (LPWORD)ul;
}
int nCopyAnsiToWideChar(LPWORD lpWCStr, LPSTR lpAnsiln)
{
int cchAnsi=lstrlen(lpAnsiln);
return MultiByteToWideChar(GetACP(), MB_PRECOMPOSED, lpAnsiln, cchAnsi, lpWCStr, cchAnsi) + 1;
}
void DlgTemplate(PWORD& p, DWORD lStyle, int items, int x, int y, int cx, int cy, LPSTR txt)
{
*p++=LOWORD(lStyle);
*p++=HIWORD(lStyle);
*p++=0;
*p++=0;
*p++=items;
*p++=x;
*p++=y;
*p++=cx;
*p++=cy;
*p++=0;
*p++=0;
p+=nCopyAnsiToWideChar(p,TEXT(txt)); //***liv*** Сократил немного (не ошибка)
}
//***liv*** Раз параметр "класс" не строка, а слово, то небольшое изменение в параметре
void DlgItemTemplate(PWORD& p, DWORD lStyle, int x, int y, int cx, int cy, WORD id, WORD wClass, LPSTR txt)
{
p=lpwAlign((LPWORD)p); //***liv*** Выравнивание лучше перемести в начало органа управления
*p++=LOWORD(lStyle);
*p++=HIWORD(lStyle);
*p++=0;
*p++=0;
*p++=x;
*p++=y;
*p++=cx;
*p++=cy;
*p++=id;
*p++=0xffff; //***liv*** Пропущеное поле!
*p++=wClass; //***liv*** Класс
p+=nCopyAnsiToWideChar(p, TEXT(txt)); //***liv*** Сократил немного (не ошибка)
//***liv*** Проверка на длину лишняя - получится автоматически и так
*p++=0; //***liv*** Пропущенное поле параметра
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Functions.h //***liv*** не CPP :)
#include <windows.h>
#include <stdlib.h>
#include <math.h>
#include <prsht.h>
#include <commctrl.h>
#pragma comment (lib, "comctl32.lib")
//***liv*** Классы стандартных органов управления
#define S_BUTTON 0x0080
#define S_EDIT 0x0081
#define S_STATIC 0x0082
#define S_LISTBOX 0x0083
#define S_SCROLLBAR 0x0084
#define S_COMBOBOX 0x0085
extern HINSTANCE hInstance;
BOOL RegClass (WNDPROC, LPCTSTR, UINT);
LPWORD lpwAlign(LPWORD);
int nCopyAnsiToWideChar(LPWORD, LPSTR);
void DlgTemplate(PWORD &, DWORD, int, int, int, int, int, LPSTR);
//***liv*** Тип параметра - не LPTR, а WORD
void DlgItemTemplate(PWORD &, DWORD, int, int, int, int, WORD, WORD, LPSTR);
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен