Jak fungují taby C/C++

Jak fungují taby C/C++
« kdy: 29. 06. 2015, 14:21:10 »
Nevím jaké slovo se pro to používá, anglicky tabs, česky možná ouška na které klikáte v okně když chcete přepnout ze stránky na stránku.
Snažím se porozumět zdrojovému kódu jednoho programu. Našel jsem místo ve kterém se vytváří jednotlivé stránky a okno, ale co mě zajímá je jak to funguje když kliknu na "ouško" a prvky v okně se přepíší těmi aktuálními prvky. Nemohu totiž v tom kódu najít nic co by toto překreslování provádělo. Je tam akorád jedna smyčka která se spouští jen jednou při iniciaci okna.

http://codepaste.net/184rjv

Našel jsem:

Kód: [Vybrat]
/* Each editor's property page proc (in order of Dialog ID). */
DLGPROC procs[NUM_PAGES] =
{
&IMsgsDlgProc,
&PlyDlgProc,
&VictDlgProc,
&DisDlgProc,
&MapDlgProc,
&UnitDlgProc,
&TrigDlgProc
};

Sheet_HandleCommand - handles all commands routed to property sheet

A funkce na vytváření sheetu:
Kód: [Vybrat]

/*
MakeSheet: Creates the main property sheet window.

Parameters:
HINSTANCE app: Handle to the application loading the sheet.

Note: Called once and only once by WinMain().
*/
HWND MakeSheet(HINSTANCE app)
{
PROPSHEETHEADER header;
HPROPSHEETPAGE pages[NUM_PAGES];
PROPSHEETPAGE pg; //used to create each page
HWND sheet;

//create pages

pg.dwSize = sizeof(PROPSHEETPAGE);
pg.dwFlags = PSP_DEFAULT;
pg.hInstance = app;

for (int i = 0; i < NUM_PAGES; i++)
{
pg.pszTemplate = MAKEINTRESOURCE(IDD_MSGS + i); //template IDs are in display order
pg.pfnDlgProc = procs[i];
pg.lParam = 0;
pages[i] = CreatePropertySheetPage(&pg);
}

//create sheet

header.dwSize = sizeof(header);
header.dwFlags = PSH_MODELESS | PSH_USECALLBACK |
PSH_NOAPPLYNOW | PSH_NOCONTEXTHELP | PSH_USEICONID;
header.hwndParent = NULL;
header.hInstance = app;
header.pszIcon = MAKEINTRESOURCE(IDI_LOGO);
header.pszCaption = szTitle;
header.nPages = NUM_PAGES;
header.nStartPage = 0;
header.phpage = pages;

header.pfnCallback = &PropSheetProc;

sheet = (HWND)PropertySheet(&header);

//add status bar here (can't be done in PropertySheetProc)
propdata.statusbar = CreateWindow(STATUSCLASSNAME, welcome,
WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
sheet, (HMENU)IDS_MAIN, aokts, NULL);

return sheet;
}

Všechno by přitom mělo být v tomto souboru, protože je to hlavní soubor a ten obsahuje vše podstatné k hlavnímu oknu.


Re:Jak fungují taby C/C++
« Odpověď #1 kdy: 29. 06. 2015, 14:52:37 »
Ještě jsem našel inkludované funkce:

Kód: [Vybrat]
#undef PropSheet_IsDialogMessage
inline LRESULT PropSheet_IsDialogMessage(HWND propsheet, PMSG msg)
{
return SendMessage(propsheet, PSM_ISDIALOGMESSAGE, 0, (LPARAM)msg);
}

#undef PropSheet_GetCurrentPageHwnd
inline HWND PropSheet_GetCurrentPageHwnd(HWND propsheet)
{
return (HWND)SendMessage(propsheet, PSM_GETCURRENTPAGEHWND, 0, 0);
}

Re:Jak fungují taby C/C++
« Odpověď #2 kdy: 29. 06. 2015, 15:59:45 »
Už jsem na to přišel jak to funguje.
Hned na začátku je

Kód: [Vybrat]
DLGPROC procs[NUM_PAGES] =
{
&IMsgsDlgProc,
&PlyDlgProc,
&VictDlgProc,
&DisDlgProc,
&MapDlgProc,
&UnitDlgProc,
&TrigDlgProc
};

Ty procedury jsou ale nadeklarované a nadefinované v jiném souboru - editors.h:
Kód: [Vybrat]
extern struct PropSheetData
{
int pindex; //current player number
class Player *p; //current player struct
int sel0, sel1; //page dependant, should be reset on SETACTIVE
HWND statusbar;
HWND mapview;
HMENU menu;
UINT tformat, ecformat, mcformat; //clipboard formats
} propdata;

INT_PTR CALLBACK IMsgsDlgProc(HWND page, UINT msg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK PlyDlgProc(HWND page, UINT msg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK VictDlgProc(HWND page, UINT msg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK DisDlgProc(HWND page, UINT msg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK MapDlgProc(HWND page, UINT msg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK UnitDlgProc(HWND page, UINT msg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK TrigDlgProc(HWND page, UINT msg, WPARAM wParam, LPARAM lParam);

A dále je definice v modulech, např. unitedit.cpp
Kód: [Vybrat]
BOOL Units_HandleInit(HWND dialog)
{
Combo_Fill(dialog, IDC_U_LIST_PLAYERS, Player::names, NUM_PLAYERS);
Combo_Fill(dialog, IDC_U_ROTATE, rotates, NUM_ROTATES);
Combo_Fill(dialog, IDC_U_SORT, sorts, NUM_SORTS);
SendDlgItemMessage(dialog, IDC_U_SORT, CB_SETCURSEL, 0, 0);

LCombo_Fill(dialog, IDC_U_TYPE, esdata.unitgroups.head(), L"All");
UnitList_FillGroup(GetDlgItem(dialog, IDC_U_UNIT), NULL);

//set edit control limits
SendDlgItemMessage(dialog, IDC_U_X, EM_SETLIMITTEXT, 5, 0);
SendDlgItemMessage(dialog, IDC_U_Y, EM_SETLIMITTEXT, 5, 0);

return TRUE;
}

INT_PTR CALLBACK UnitDlgProc(HWND dialog, UINT msg, WPARAM wParam, LPARAM lParam)
{
INT_PTR ret = FALSE;

try
{
switch (msg)
{
case WM_INITDIALOG:
ret = Units_HandleInit(dialog);
break;

case WM_COMMAND:
ret = 0;
Units_HandleCommand(dialog, HIWORD(wParam), LOWORD(wParam), (HWND)lParam);
break;

case WM_NOTIFY:
{
NMHDR *header = (NMHDR*)lParam;
switch (header->code)
{
case PSN_SETACTIVE:
SendDlgItemMessage(
dialog, IDC_U_LIST_PLAYERS, CB_SETCURSEL, propdata.pindex, 0);
Units_Reset(dialog);
break;

case PSN_KILLACTIVE:
Units_Save(dialog);
SendMessage(
propdata.mapview, MAP_UnhighlightPoint, MAP_UNHIGHLIGHT_ALL, 0);
}
}
break;

case WM_VKEYTOITEM:
if (LOWORD(wParam) == VK_DELETE)
Units_HandleDelete(dialog);
ret = -1;
break;

case AOKTS_Loading:
Units_Reset(dialog);
break;

case AOKTS_Saving:
Units_Save(dialog);
break;

case MAP_Click:
Units_HandleMapClick(dialog, LOWORD(lParam), HIWORD(lParam));
break;
}
}
catch (std::exception& ex)
{
// Show a user-friendly message, bug still crash to allow getting all
// the debugging info.
unhandledExceptionAlert(dialog, msg, ex);
throw;
}

return ret;
}