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; }