SftTree/DLL 7.5 - Tree Control
SftBox/OCX 5.0 - Combo Box Control
SftButton/OCX 3.0 - Button Control
SftMask/OCX 7.0 - Masked Edit Control
SftTabs/OCX 6.5 - Tab Control (VB6 only)
SftTree/OCX 7.5 - Tree Control
SftPrintPreview/DLL 2.0 - Print Preview Control (discontinued)
SftTree/DLL 7.5 - Tree Control
SftBox/OCX 5.0 - Combo Box Control
SftButton/OCX 3.0 - Button Control
SftDirectory 3.5 - File/Folder Control (discontinued)
SftMask/OCX 7.0 - Masked Edit Control
SftOptions 1.0 - Registry/INI Control (discontinued)
SftPrintPreview/OCX 1.0 - Print Preview Control (discontinued)
SftTabs/OCX 6.5 - Tab Control (VB6 only)
SftTree/OCX 7.5 - Tree Control
SftTabs/NET 6.0 - Tab Control (discontinued)
SftTree/NET 2.0 - Tree Control
This sample illustrates a tabbed window.
The source code is located at C:\Program Files (x86)\Softelvdm\SftTabs DLL 6.5\Samples\C\Window\Window.c or C:\Program Files\Softelvdm\SftTabs DLL 6.5\Samples\C\Window\Window.c (on 32-bit Windows versions).
/****************************************************************************/
/* SftTabs/DLL 6.5 - Tab Control for C/C++ */
/* Copyright (C) 1994, 2017 Softel vdm, Inc. All Rights Reserved. */
/****************************************************************************/
#include <windows.h>
#include "sfttb.h" /* SftTabs/DLL Header File */
#include "resource.h" // application resources
/**********************************************************************/
/* Globals */
/**********************************************************************/
HINSTANCE g_hInst;
/**********************************************************************/
/* SDI Frame Window */
/**********************************************************************/
#if defined(_WIN64)
#define Frame_GetPtr(hwnd) (PFRAME)GetWindowLongPtr((hwnd), 0)
#define Frame_SetPtr(hwnd, ptr) SetWindowLongPtr((hwnd), 0, (LONG_PTR)(ptr))
#else
#define Frame_GetPtr(hwnd) (PFRAME)GetWindowLong((hwnd), 0)
#define Frame_SetPtr(hwnd, ptr) SetWindowLong((hwnd), 0, (LONG)(ptr))
#endif
typedef struct tagFRAME
{
HWND hwnd; // the frame window
HWND hwndStatic; // static control
HWND hwndTab; // tab control
HWND hwndFrame; // the frame window containing the pages
} FRAME, NEAR* PFRAME;
#define IDC_TAB 101 /* tab control ID */
#define IDC_LIST 102 // control ids for control on frame window
#define IDC_EDIT 103
/**********************************************************************/
/* ListBox and Edit Control Callback */
/**********************************************************************/
HWND CALLBACK Page1_Callback(BOOL fCreate, HWND hwndOwner, HWND hwndPage, HWND hwndTab)
{
if (fCreate) { // creating a new page
if (hwndPage) {
// already created, we could do some initialization here.
// this will be called every time the page becomes active.
// The WM_SHOWWINDOW message is also sent to the page and could
// be used to determine activation/deactivation of the page.
return NULL; // return NULL, ignored
} else {
// Create the page.
// You can create and initialize any type of window here, not just dialogs.
// Use CreateWindow to create other windows. Don't specify WS_VISIBLE, but
// make sure you use WS_TABSTOP.
HWND hwndList;
hwndList = CreateWindow( /* Create the list box */
TEXT("LISTBOX"), /* Window Class */
TEXT(""), /* Window Title (not used) */
WS_CHILD| /* Window Style */
WS_TABSTOP|LBS_NOTIFY|LBS_NOINTEGRALHEIGHT,
0, 0, /* x, y */
0, 0, /* cx, cy */
hwndOwner, /* Parent Window */
(HMENU) IDC_LIST, /* control ID */
g_hInst, /* Application Instance */
NULL); /* creation data */
if (hwndList == NULL) /* create failed */
return NULL;
SendMessage(hwndList, WM_SETFONT, SendMessage(hwndTab, WM_GETFONT, 0, 0L), FALSE);
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR) TEXT("Item 1"));
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR) TEXT("Item 2"));
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR) TEXT("Item 3"));
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR) TEXT("Item 4"));
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR) TEXT("Item 5"));
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR) TEXT("Item 6"));
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR) TEXT("This is a listbox."));
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR) TEXT("Click a tab or use Alt-xxx to"));
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR) TEXT("switch to another tab."));
SendMessage(hwndList, LB_SETCURSEL, 0, 0L);
SftTabs_SetPageActive(hwndList, hwndTab, NULL);
return hwndList;
}
} else { // destroying page
if (hwndOwner) // - because we're switching away
return hwndPage; // keep the window handle, don't destroy it
else { // - because we're closing the main dialog
DestroyWindow(hwndPage);
return NULL;
}
}
}
HWND CALLBACK Page2_Callback(BOOL fCreate, HWND hwndOwner, HWND hwndPage, HWND hwndTab)
{
if (fCreate) { // creating a new page
if (hwndPage) {
// already created, we could do some initialization here.
// this will be called every time the page becomes active.
// The WM_SHOWWINDOW message is also sent to the page and could
// be used to determine activation/deactivation of the page.
SetWindowText(hwndPage, TEXT("Thank you for coming back."));
return NULL; // return NULL, ignored
} else {
// create the window
HWND hwnd;
// Create the edit control
// You can create and initialize any type of window here, not just dialogs.
// Use CreateWindow to create other windows. Don't specify WS_VISIBLE, but
// make sure you use WS_TABSTOP.
hwnd = CreateWindow( /* Create the list box */
TEXT("EDIT"), /* Window Class */
TEXT(""), /* Window Title (not used) */
WS_CHILD| /* Window Style */
WS_TABSTOP|ES_MULTILINE|ES_WANTRETURN,
0, 0, /* x, y */
0, 0, /* cx, cy */
hwndOwner, /* Parent Window */
(HMENU) IDC_EDIT, /* control ID */
g_hInst, /* Application Instance */
NULL); /* creation data */
if (hwnd == NULL) /* create failed */
return NULL;
SendMessage(hwnd, WM_SETFONT, SendMessage(hwndTab, WM_GETFONT, 0, 0L), FALSE);
SetWindowText(hwnd, TEXT("This is an edit control.\r\nClick a tab or use Alt-xxx to switch to another tab. "
TEXT(" Make sure to look at the \"Dialog\" tab also.")));
SftTabs_SetPageActive(hwnd, hwndTab, NULL);
return hwnd;
}
} else { // destroying page
if (hwndOwner) // - because we're switching away
return hwndPage; // keep the window handle, don't destroy it
else { // - because we're closing the main dialog
DestroyWindow(hwndPage);
return NULL;
}
}
}
/**********************************************************************/
/* Dialog Proc */
/**********************************************************************/
BOOL CALLBACK Page3_DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG: {
// initialize this dialog
SetWindowText(GetDlgItem(hwndDlg, IDC_P3_EDIT1), TEXT("Click another tab"));
SendMessage(GetDlgItem(hwndDlg, IDC_P3_EDIT1), BM_SETCHECK, 0, 0);
// initialize page. We'll use the edit window as frame window
SftTabs_SetPageActive(hwndDlg, (HWND) lParam, NULL);
return !SftTabs_IsRegisteredDialog(GetParent(hwndDlg));
}
}
if (SftTabs_HandleDialogMessage(hwndDlg, msg, wParam, lParam))
return TRUE;
return FALSE;
}
HWND CALLBACK Page3_Callback(BOOL fCreate, HWND hwndOwner, HWND hwndPage, HWND hwndTab)
{
if (fCreate) { // creating a new page
if (hwndPage)
// already created, we could do some initialization here.
// this will be called every time the page becomes active.
// The WM_SHOWWINDOW message is also sent to the page and could
// be used to determine activation/deactivation of the page.
return NULL; // return NULL, ignored
else
// Create the page.
// You can create and initialize any type of window here, not just dialogs.
// Use CreateWindow to create other windows.
return CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), hwndOwner, (DLGPROC)Page3_DialogProc,
(LPARAM)hwndTab);// pass tab control as data
} else { // destroying page
if (hwndOwner) // - because we're switching away
return hwndPage; // keep the window handle, don't destroy it
else { // - because we're closing the main dialog
DestroyWindow(hwndPage);
return NULL;
}
}
}
/**********************************************************************/
/* Frame Window */
/**********************************************************************/
/*- Tab Control Initialization Data --------------------------------------------*/
static const SFTTABS_CONTROL CtlInit = {
SFTTABSSTYLE_MODERN_II, /* tab style */
1, /* number of rows */
0, /* number of tabs per row (if fFixed) */
0, /* width of left margin */
0, /* width of right margin */
FALSE, /* same width for all tabs */
FALSE, /* Client area wanted */
FALSE, /* allow multiline label text */
TRUE, /* use with dialog */
FALSE, /* use specified background color only for text */
TRUE, /* scrollable tabs */
FALSE, /* hide scroll buttons */
TRUE, /* bold font for active tab wanted */
FALSE, /* fill rows completely */
NULL, /* scroll button bitmap */
NULL, /* Dialog data associated with active tab */
NULL, /* Dialog window handle associated with active tab */
NULL, /* Frame, used as client area */
TRUE, /* Tooltips wanted */
FALSE, /* drop text if it doesn't fit */
FALSE, /* conditional scroll buttons */
BMBUTTONSTYLE_THEME_SCROLL, /* scroll button style */
FALSE, /* display ... if truncated */
TRUE, /* Flyby highlighting */
FALSE, /* use client area colors in partially obscured frames */
TRUE, /* scroll buttons on left side */
0, /* row indentation */
FALSE, /* don't show truncated pattern for clipped tab */
TRUE, /* full size scroll buttons */
FALSE, /* use themes on Windows XP */
FALSE, /* use exact window region */
FALSE, /* always show prefix _ */
0,0,0,0, /* animation values */
NULL, /* disabled button bitmap */
TRUE, /* focus rectangle if the control has i/p focus */
FALSE, /* TRUE if Close button wanted */
FALSE, /* TRUE if Close button disabled */
FALSE, /* TRUE if WM_CLOSE message wanted */
FALSE, /* TRUE if Minimize, Restore, Close buttons are full size */
SFTTABS_BUTTON_NEAR, /* scroll button alignment */
SFTTABS_BUTTON_NEAR, /* Minimize, Restore, Close button alignment */
FALSE, /* TRUE if Minimize button wanted */
FALSE, /* TRUE if Minimize button disabled */
FALSE, /* TRUE if Restore button wanted */
FALSE, /* TRUE if Restore button disabled */
NULL, /* Close, Minimize, Restore button bitmap */
NULL, /* Close, Minimize, Restore disabled button bitmap */
TEXT("Scroll Left"), /* scroll left button tooltip */
TEXT("Scroll Right"), /* scroll button tooltip */
TEXT(""), /* Close button tooltip */
TEXT(""), /* Minimize button tooltip */
TEXT(""), /* Restore button tooltip */
0, /* custom modifications */
0, /* forced height/width depending on tab style - 0 to ignore */
FALSE, /* switch tabs on button release (or down if FALSE) */
FALSE, /* Rendering compatible with pre-6.0 */
FALSE, /* don't display clientarea border - select styles only */
SFTTABS_TABS_LEFT, /* alignment of tabs on all rows */
SFTTABS_LAYOUT_DISTRIBUTE, /* distribution of tabs on rows */
0, 0, /* minimum and maximum number of rows for autoflow layout (none specified) */
TRUE, /* reorderable tabs */
FALSE, /* drag & drop */
};
static const SFTTABS_TAB Tab0 = { /*&Listbox */
RGB(129,169,226), RGB(0,0,0), /* background, foreground color */
RGB(129,169,226), RGB(0,0,0), /* background, foreground color (when selected) */
{ SFTTABS_GRAPH_NONE, 0 }, /* location */
TRUE, /* enabled/disabled */
0, /* userdata */
(SFTTABS_DWORD_PTR) Page1_Callback, /* user supplied tab callback */
NULL, /* reserved */
RGB(0,0,255), /* Flyby foreground color */
RGB(129,169,226), /* Client area background color */
0,0,0,0, /* animation values */
NULL, /* tab-specific ImageList handle*/
FALSE, /* hidden tab */
RGB(222,236,254), /* gradient fill background color */
RGB(129,169,226),
RGB(222,236,254), /* gradient fill background color, active tab */
RGB(129,169,226),
RGB(129,169,226), /* gradient fill client area color */
RGB(222,236,254),
0,0,0, /* TabPicture, TabPictureDisabled and TabPictureHot */
FALSE, /* has tab close button */
0,0,0,0,0, /* gap2, TabPicture2, TabPicture2Active, TabPicture2Disabled, TabPicture2Hot */
};
static const SFTTABS_TAB Tab1 = { /*&Edit Control */
RGB(129,169,226), RGB(0,0,0), /* background, foreground color */
RGB(129,169,226), RGB(0,0,0), /* background, foreground color (when selected) */
{ SFTTABS_GRAPH_NONE, 0 }, /* location */
TRUE, /* enabled/disabled */
0, /* userdata */
(SFTTABS_DWORD_PTR) Page2_Callback, /* user supplied tab callback */
NULL, /* reserved */
RGB(0,0,255), /* Flyby foreground color */
RGB(129,169,226), /* Client area background color */
0,0,0,0, /* animation values */
NULL, /* tab-specific ImageList handle*/
FALSE, /* hidden tab */
RGB(222,236,254), /* gradient fill background color */
RGB(129,169,226),
RGB(222,236,254), /* gradient fill background color, active tab */
RGB(129,169,226),
RGB(129,169,226), /* gradient fill client area color */
RGB(222,236,254),
0,0,0, /* TabPicture, TabPictureDisabled and TabPictureHot */
FALSE, /* has tab close button */
0,0,0,0,0, /* gap2, TabPicture2, TabPicture2Active, TabPicture2Disabled, TabPicture2Hot */
};
static const SFTTABS_TAB Tab2 = { /*&Dialog */
RGB(129,169,226), RGB(0,0,0), /* background, foreground color */
RGB(129,169,226), RGB(0,0,0), /* background, foreground color (when selected) */
{ SFTTABS_GRAPH_NONE, 0 }, /* location */
TRUE, /* enabled/disabled */
0, /* userdata */
(SFTTABS_DWORD_PTR) Page3_Callback, /* user supplied tab callback */
NULL, /* reserved */
RGB(0,0,255), /* Flyby foreground color */
RGB(129,169,226), /* Client area background color */
0,0,0,0, /* animation values */
NULL, /* tab-specific ImageList handle*/
FALSE, /* hidden tab */
RGB(222,236,254), /* gradient fill background color */
RGB(129,169,226),
RGB(222,236,254), /* gradient fill background color, active tab */
RGB(129,169,226),
RGB(129,169,226), /* gradient fill client area color */
RGB(222,236,254),
0,0,0, /* TabPicture, TabPictureDisabled and TabPictureHot */
FALSE, /* has tab close button */
0,0,0,0,0, /* gap2, TabPicture2, TabPicture2Active, TabPicture2Disabled, TabPicture2Hot */
};
LRESULT CALLBACK Frame_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
PFRAME pfrm = Frame_GetPtr(hwnd);
if (pfrm == NULL) {
if (msg == WM_NCCREATE) {
pfrm = (PFRAME)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, sizeof(FRAME));
if (pfrm == NULL)
return 0;
pfrm->hwnd = hwnd;
Frame_SetPtr(hwnd, pfrm);
} else
return DefWindowProc(hwnd, msg, wParam, lParam);
}
if (msg == WM_NCDESTROY) {
LRESULT lRes = DefWindowProc(hwnd, msg, wParam, lParam);
LocalFree((HLOCAL)pfrm);
pfrm = NULL;
Frame_SetPtr(hwnd, NULL);
}
switch (msg) {
case WM_CREATE: {
int index;
/* This static window is just a filler window above the tab control */
/* We only need it to get the right background color above the tab control */
pfrm->hwndStatic = CreateWindow(/* Create a static window */
TEXT("STATIC"), /* Window Class */
TEXT(""), /* Window Title (not used) */
WS_CHILD|WS_VISIBLE, /* Window Style */
0, 0, /* x, y */
0, 0, /* cx, cy */
hwnd, /* Parent Window */
NULL, /* control ID */
g_hInst, /* Application Instance */
NULL); /* creation data */
if (pfrm->hwndStatic == NULL) /* create failed */
return -1;
/* Create the tab control */
pfrm->hwndTab = CreateWindow( /* Create the tab control */
TEXT(SFTTABS_CLASS), /* Window Class */
TEXT(""), /* Window Title (not used) */
WS_CHILD|WS_VISIBLE| /* Window Style */
WS_CLIPCHILDREN|WS_TABSTOP|
SFTTABSSTYLE_STANDARD,
0, 0, /* x, y */
0, 0, /* cx, cy */
hwnd, /* Parent Window */
(HMENU) IDC_TAB, /* Tab control ID */
g_hInst, /* Application Instance */
NULL); /* creation data */
if (pfrm->hwndTab == NULL) /* create failed */
return -1;
/* Create a frame window. This frame window will be used by SftTabs/DLL */
/* to resize the pages that are attached to the tabs */
pfrm->hwndFrame = CreateWindow( /* Create a static window */
TEXT("STATIC"), /* Window Class */
TEXT(""), /* Window Title (not used) */
WS_CHILD, /* Window Style NOTE: IT'S NOT VISIBLE */
0, 0, /* x, y */
0, 0, /* cx, cy */
hwnd, /* Parent Window */
NULL, /* control ID */
g_hInst, /* Application Instance */
NULL); /* creation data */
if (pfrm->hwndFrame == NULL) /* create failed */
return -1;
/* Initialization is faster if we set redraw off */
SendMessage(pfrm->hwndTab, WM_SETREDRAW, (WPARAM)FALSE, 0);
/* We are using new features */
SftTabs_SetVersion(pfrm->hwndTab, SFTTABS_6_5);
index = SftTabs_AddTab(pfrm->hwndTab, TEXT("&Listbox"));
SftTabs_SetToolTip(pfrm->hwndTab, index, TEXT("A standard listbox is attached to this tab"));
SftTabs_SetTabInfo(pfrm->hwndTab, index, &Tab0);
index = SftTabs_AddTab(pfrm->hwndTab, TEXT("&Edit Control"));
SftTabs_SetToolTip(pfrm->hwndTab, index, TEXT("A standard edit control is attached to this tab"));
SftTabs_SetTabInfo(pfrm->hwndTab, index, &Tab1);
index = SftTabs_AddTab(pfrm->hwndTab, TEXT("&Dialog"));
SftTabs_SetToolTip(pfrm->hwndTab, index, TEXT("A dialog is attached to this tab"));
SftTabs_SetTabInfo(pfrm->hwndTab, index, &Tab2);
SftTabs_SetControlInfo(pfrm->hwndTab, &CtlInit);
SftTabs_SetCurrentTab(pfrm->hwndTab, 0);
// Make sure to turn redraw back on
SendMessage(pfrm->hwndTab, WM_SETREDRAW, (WPARAM)TRUE, 0);
InvalidateRect(pfrm->hwndTab, NULL, TRUE);
// Activate current page. Note the frame window is supplied in this example.
// if your tab control has a client area (see fClientArea), you don't need a
// frame window
SftTabs_ActivatePage(hwnd, pfrm->hwndTab, pfrm->hwndFrame, TRUE);
// Mark the window as a main, tabbed windows (so accel. keys work) by registering it.
// Register the window AFTER activating the current page
SftTabs_RegisterWindow(hwnd);
return 0L;
}
case WM_SIZE: {
RECT rect;
// resize all child windows
// get frame window dimension
GetClientRect(hwnd, &rect);
// calculate position of tab control
if (pfrm->hwndTab) {
SFTTABS_CONTROL Ctl;
// Get tab control info
SftTabs_GetControlInfo(pfrm->hwndTab, &Ctl);
// Ctl.naturalSize has best height for this tab control
rect.top += 5+Ctl.naturalSize;
}
// reposition static control which serves as a filler window above the tab control
if (pfrm->hwndStatic)
MoveWindow(pfrm->hwndStatic, rect.left, 0, rect.right-rect.left, 5, TRUE);
// now reposition tab control
if (pfrm->hwndTab)
MoveWindow(pfrm->hwndTab, 0, 5, rect.right-rect.left, rect.top-5, TRUE);
// reposition the frame window
if (pfrm->hwndFrame)
MoveWindow(pfrm->hwndFrame, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE);
// now that the frame window has the right size, resize all pages
if (pfrm->hwndTab)
SftTabs_ResizePages(pfrm->hwndTab);
return 0L;
}
case WM_SETFOCUS:
// When we get the focus, set it to the tab control
SetFocus(pfrm->hwndTab);
return 0L;
case WM_CLOSE:
DestroyWindow(hwnd);
PostQuitMessage(0);
return 0L;
case WM_COMMAND: {
HWND hwndCtl = (HWND) lParam;
int id = LOWORD(wParam);
int code = HIWORD(wParam);
if (hwndCtl) {
switch (id) {
case IDC_TAB:
switch (code) {
case SFTTABSN_SWITCHING:// we're about to switch away from
// the current page. If you need to know what the new
// page will be use SftTabs_GetNextTab(hwndCtl).
if (!SftTabs_DeactivatePage(hwnd, hwndCtl))
// couldn't deactivate current page, so don't switch
SendMessage(hwndCtl, WM_CANCELMODE, 0, 0);
break;
case SFTTABSN_SWITCHED:// we switched to a new page
SftTabs_ActivatePage(hwnd, hwndCtl, NULL, FALSE);
break;
case SFTTABSN_DRAGDROP: { // {popup "tab reordering" pop_tabreordering}
SFTTABS_DRAGINFO dragInfo;
SftTabs_GetDragInfo(hwndCtl, &dragInfo);
if (dragInfo.targetAllowed) {
SftTabs_MoveTab(hwndCtl, dragInfo.reorderTab, dragInfo.targetTab);
}
break;
}
}
break;
case IDOK:
case IDCANCEL:
if (code == BN_CLICKED)
SendMessage(hwnd, WM_COMMAND, id, 0);
break;
}
} else {
switch (id) {
case IDM_EXIT:
// The currently active page will be called with a
// WM_QUERYENDSESSION/SftTabs_GetEndPageMessage message
// to determine whether it can be closed
if (SftTabs_ClosePossible(hwnd, GetDlgItem(hwnd, IDC_TAB))) {
DestroyWindow(hwnd);
PostQuitMessage(0);
}
break;
}
}
break;
}
case WM_DESTROY:
// Unregister, or the window properties used won't be removed
SftTabs_UnregisterWindow(hwnd);
// destroy all pages (BEFORE destroying tab control)
SftTabs_Destroy(hwnd, pfrm->hwndTab);
if (pfrm->hwndStatic)
DestroyWindow(pfrm->hwndStatic);
if (pfrm->hwndFrame)
DestroyWindow(pfrm->hwndFrame);
if (pfrm->hwndTab)
DestroyWindow(pfrm->hwndTab);
break;
// In order to support tabbing between the SftTabs control and non-dialog
// windows (such as the listbox and edit control), the WM_NEXTDLGCTL message
// has to be handled. This is not a function of SftTabs and is only included
// as an example.
case WM_NEXTDLGCTL: {
HWND hwndCtl;
// regular windows don't handle this message
if (LOWORD(lParam))
hwndCtl = (HWND)(UINT_PTR) wParam;
else
hwndCtl = GetNextDlgTabItem(hwnd, GetFocus(), (BOOL) wParam);
SetFocus(hwndCtl);
return 0L;
}
}
// Call SftTabs/DLL to let it handle some messages (mostly for keyboard accel. keys)
{
LRESULT lRes;
if (SftTabs_HandleWindowMessage(hwnd, msg, wParam, lParam, &lRes))
return lRes;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
/**********************************************************************/
/* WinMain */
/**********************************************************************/
int PASCAL WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int cmdShow)
{
HWND hwndMain;
MSG msg;
// Global initialization
if (hinstPrev == NULL) {
// register frame window
WNDCLASS cls;
cls.hCursor = LoadCursor(NULL, IDC_ARROW);
cls.hIcon = LoadIcon(hinst, MAKEINTRESOURCE(IDI_ICON1));
cls.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU);
cls.hInstance = hinst;
cls.lpszClassName = TEXT("SampleFrame");
cls.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
cls.lpfnWndProc = (WNDPROC) Frame_WndProc;
cls.style = CS_DBLCLKS;
cls.cbWndExtra = sizeof(PFRAME);
cls.cbClsExtra = 0;
if (!RegisterClass(&cls))
return FALSE;
}
SftTabs_RegisterApp(hinst); /* Register with SftTabs/DLL */
// Instance Initialize
g_hInst = hinst;
// Create the frame window
if ((hwndMain = CreateWindowEx(
0L,
TEXT("SampleFrame"),
TEXT("Sample"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL,
NULL,
hinst,
NULL)) == NULL)
return FALSE;
ShowWindow(hwndMain, cmdShow);
// Run
while (GetMessage(&msg, NULL, 0, 0)) {
// Because the frame window will contain a dialog, we'll need to get things
// going with this IsDialogMessage call, otherwise the modeless dialog(s)
// message filters won't get called.
// As an extra bonus, the IsDialogMessage implements proper tabbing between
// the tab control and the other child windows of the frame window.
if (IsDialogMessage(hwndMain, &msg))
;
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// Terminate
SftTabs_UnregisterApp(hinst); /* Unregister from SftTabs/DLL */
return (int) msg.wParam;
}
