Bagikan melalui


Menggunakan Kotak Dialog Umum

Bagian ini mencakup tugas yang memanggil kotak dialog umum:

Memilih Warna

Topik ini menjelaskan kode sampel yang menampilkan kotak dialog Warna sehingga pengguna dapat memilih warna. Kode sampel pertama kali menginisialisasi struktur CHOOSECOLOR , lalu memanggil fungsi ChooseColor untuk menampilkan kotak dialog. Jika fungsi mengembalikan TRUE, menunjukkan bahwa pengguna memilih warna, kode sampel menggunakan warna yang dipilih untuk membuat kuas solid baru.

Contoh ini menggunakan struktur CHOOSECOLOR untuk menginisialisasi kotak dialog sebagai berikut:

  • Menginisialisasi anggota lpCustColors dengan penunjuk ke array nilai statis. Warna dalam array awalnya hitam, tetapi array statis mempertahankan warna kustom yang dibuat oleh pengguna untuk panggilan ChooseColor berikutnya.
  • Mengatur bendera CC_RGBINIT dan menginisialisasi anggota rgbResult untuk menentukan warna yang awalnya dipilih saat kotak dialog terbuka. Jika tidak ditentukan, pilihan awal berwarna hitam. Contoh menggunakan variabel statis rgbCurrent untuk mempertahankan nilai yang dipilih antara panggilan ke ChooseColor.
  • Mengatur bendera CC_FULLOPEN sehingga ekstensi warna kustom kotak dialog selalu ditampilkan.
CHOOSECOLOR cc;                 // common dialog box structure 
static COLORREF acrCustClr[16]; // array of custom colors 
HWND hwnd;                      // owner window
HBRUSH hbrush;                  // brush handle
static DWORD rgbCurrent;        // initial color selection

// Initialize CHOOSECOLOR 
ZeroMemory(&cc, sizeof(cc));
cc.lStructSize = sizeof(cc);
cc.hwndOwner = hwnd;
cc.lpCustColors = (LPDWORD) acrCustClr;
cc.rgbResult = rgbCurrent;
cc.Flags = CC_FULLOPEN | CC_RGBINIT;
 
if (ChooseColor(&cc)==TRUE) 
{
    hbrush = CreateSolidBrush(cc.rgbResult);
    rgbCurrent = cc.rgbResult; 
}

Memilih Font

Topik ini menjelaskan kode sampel yang menampilkan kotak dialog Font sehingga pengguna dapat memilih atribut font. Kode sampel pertama kali menginisialisasi struktur CHOOSEFONT , lalu memanggil fungsi ChooseFont untuk menampilkan kotak dialog.

Contoh ini mengatur bendera CF_SCREENFONTS untuk menentukan bahwa kotak dialog hanya boleh menampilkan font layar. Ini mengatur bendera CF_EFFECTS untuk menampilkan kontrol yang memungkinkan pengguna memilih opsi coretan, garis bawah, dan warna.

Jika ChooseFont mengembalikan TRUE, menunjukkan bahwa pengguna mengklik tombol OK , struktur CHOOSEFONT berisi informasi yang menjelaskan atribut font dan font yang dipilih oleh pengguna, termasuk anggota struktur LOGFONT yang diacu oleh anggota lpLogFont . Anggota rgbColors berisi warna teks yang dipilih. Kode sampel menggunakan informasi ini untuk mengatur font dan warna teks untuk konteks perangkat yang terkait dengan jendela pemilik.

HWND hwnd;                // owner window
HDC hdc;                  // display device context of owner window

CHOOSEFONT cf;            // common dialog box structure
static LOGFONT lf;        // logical font structure
static DWORD rgbCurrent;  // current text color
HFONT hfont, hfontPrev;
DWORD rgbPrev;

// Initialize CHOOSEFONT
ZeroMemory(&cf, sizeof(cf));
cf.lStructSize = sizeof (cf);
cf.hwndOwner = hwnd;
cf.lpLogFont = &lf;
cf.rgbColors = rgbCurrent;
cf.Flags = CF_SCREENFONTS | CF_EFFECTS;

if (ChooseFont(&cf)==TRUE)
{
    hfont = CreateFontIndirect(cf.lpLogFont);
    hfontPrev = SelectObject(hdc, hfont);
    rgbCurrent= cf.rgbColors;
    rgbPrev = SetTextColor(hdc, rgbCurrent);
 .
 .
 .
}

Membuka File

Catatan

Dimulai dengan Windows Vista, Dialog File Umum telah digantikan oleh Dialog Item Umum ketika digunakan untuk membuka file. Kami menyarankan agar Anda menggunakan API Dialog Item Umum alih-alih API Dialog File Umum. Untuk informasi selengkapnya, lihat Dialog Item Umum.

Topik ini menjelaskan kode sampel yang menampilkan kotak dialog Buka sehingga pengguna dapat menentukan drive, direktori, dan nama file untuk dibuka. Kode sampel pertama kali menginisialisasi struktur OPENFILENAME , lalu memanggil fungsi GetOpenFileName untuk menampilkan kotak dialog.

Dalam contoh ini, anggota lpstrFilter adalah penunjuk ke buffer yang menentukan dua filter nama file yang dapat dipilih pengguna untuk membatasi nama file yang ditampilkan. Buffer berisi array string yang dihentikan dua null di mana setiap pasangan string menentukan filter. Anggota nFilterIndex menentukan bahwa pola pertama digunakan saat kotak dialog dibuat.

Contoh ini mengatur bendera OFN_PATHMUSTEXIST dan OFN_FILEMUSTEXIST di anggota Bendera . Bendera ini menyebabkan kotak dialog diverifikasi, sebelum kembali, bahwa jalur dan nama file yang ditentukan oleh pengguna benar-benar ada.

Fungsi GetOpenFileName mengembalikan TRUE jika pengguna mengklik tombol OK dan jalur dan nama file yang ditentukan ada. Dalam hal ini, buffer yang ditujukan oleh anggota lpstrFile berisi jalur dan nama file. Kode sampel menggunakan informasi ini dalam panggilan ke fungsi untuk membuka file.

Meskipun contoh ini tidak mengatur bendera OFN_EXPLORER , contoh ini masih menampilkan kotak dialog Buka gaya Penjelajah default. Namun, jika Anda ingin menyediakan prosedur hook atau templat kustom dan Anda menginginkan antarmuka pengguna Explorer, Anda harus mengatur bendera OFN_EXPLORER .

Catatan

Dalam bahasa pemrograman C, string yang diapit tanda kutip dihentikan null.

 

OPENFILENAME ofn;       // common dialog box structure
char szFile[260];       // buffer for file name
HWND hwnd;              // owner window
HANDLE hf;              // file handle

// Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = szFile;
// Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
// use the contents of szFile to initialize itself.
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

// Display the Open dialog box. 

if (GetOpenFileName(&ofn)==TRUE) 
    hf = CreateFile(ofn.lpstrFile, 
                    GENERIC_READ,
                    0,
                    (LPSECURITY_ATTRIBUTES) NULL,
                    OPEN_EXISTING,
                    FILE_ATTRIBUTE_NORMAL,
                    (HANDLE) NULL);

Menampilkan Kotak Dialog Cetak

Topik ini menjelaskan kode sampel yang menampilkan kotak dialog Cetak sehingga pengguna dapat memilih opsi untuk mencetak dokumen. Kode sampel pertama kali menginisialisasi struktur PRINTDLG , lalu memanggil fungsi PrintDlg untuk menampilkan kotak dialog.

Contoh ini menetapkan bendera PD_RETURNDC di anggota Bendera struktur PRINTDLG . Hal ini menyebabkan PrintDlg mengembalikan handel konteks perangkat ke printer terpilih di anggota hDC . Anda dapat menggunakan handel untuk merender output pada printer.

Pada input, kode sampel mengatur anggota hDevMode dan hDevNames ke NULL. Jika fungsi mengembalikan TRUE, anggota ini mengembalikan handel ke struktur DEVNAMES yang berisi input pengguna dan informasi tentang printer. Anda dapat menggunakan informasi ini untuk menyiapkan output yang akan dikirim ke pencetak terpilih.

PRINTDLG pd;
HWND hwnd;

// Initialize PRINTDLG
ZeroMemory(&pd, sizeof(pd));
pd.lStructSize = sizeof(pd);
pd.hwndOwner   = hwnd;
pd.hDevMode    = NULL;     // Don't forget to free or store hDevMode.
pd.hDevNames   = NULL;     // Don't forget to free or store hDevNames.
pd.Flags       = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC; 
pd.nCopies     = 1;
pd.nFromPage   = 0xFFFF; 
pd.nToPage     = 0xFFFF; 
pd.nMinPage    = 1; 
pd.nMaxPage    = 0xFFFF; 

if (PrintDlg(&pd)==TRUE) 
{
    // GDI calls to render output. 

    // Delete DC when done.
    DeleteDC(pd.hDC);
}

Menggunakan Lembar Properti Cetak

Topik ini menjelaskan kode sampel yang menampilkan lembar properti Cetak sehingga pengguna dapat memilih opsi untuk mencetak dokumen. Kode sampel pertama kali menginisialisasi struktur PRINTDLGEX , lalu memanggil fungsi PrintDlgEx untuk menampilkan lembar properti.

Kode sampel mengatur bendera PD_RETURNDC di anggota Bendera struktur PRINTDLG . Ini menyebabkan fungsi PrintDlgEx mengembalikan handel konteks perangkat ke printer yang dipilih di anggota hDC .

Pada input, kode sampel mengatur anggota hDevMode dan hDevNames ke NULL. Jika fungsi mengembalikan S_OK, anggota ini mengembalikan handel ke struktur DEVNAMES yang berisi input pengguna dan informasi tentang printer. Anda dapat menggunakan informasi ini untuk menyiapkan output yang akan dikirim ke pencetak terpilih.

Setelah operasi pencetakan selesai, kode sampel membebaskan buffer DEVMODE, DEVNAMES, dan PRINTPAGERANGE dan memanggil fungsi DeleteDC untuk menghapus konteks perangkat.

// hWnd is the window that owns the property sheet.
HRESULT DisplayPrintPropertySheet(HWND hWnd)
{
    HRESULT hResult;
    PRINTDLGEX pdx = {0};
    LPPRINTPAGERANGE pPageRanges = NULL;

    // Allocate an array of PRINTPAGERANGE structures.
    pPageRanges = (LPPRINTPAGERANGE) GlobalAlloc(GPTR, 10 * sizeof(PRINTPAGERANGE));
    if (!pPageRanges)
        return E_OUTOFMEMORY;

    //  Initialize the PRINTDLGEX structure.
    pdx.lStructSize = sizeof(PRINTDLGEX);
    pdx.hwndOwner = hWnd;
    pdx.hDevMode = NULL;
    pdx.hDevNames = NULL;
    pdx.hDC = NULL;
    pdx.Flags = PD_RETURNDC | PD_COLLATE;
    pdx.Flags2 = 0;
    pdx.ExclusionFlags = 0;
    pdx.nPageRanges = 0;
    pdx.nMaxPageRanges = 10;
    pdx.lpPageRanges = pPageRanges;
    pdx.nMinPage = 1;
    pdx.nMaxPage = 1000;
    pdx.nCopies = 1;
    pdx.hInstance = 0;
    pdx.lpPrintTemplateName = NULL;
    pdx.lpCallback = NULL;
    pdx.nPropertyPages = 0;
    pdx.lphPropertyPages = NULL;
    pdx.nStartPage = START_PAGE_GENERAL;
    pdx.dwResultAction = 0;
    
    //  Invoke the Print property sheet.
    
    hResult = PrintDlgEx(&pdx);

    if ((hResult == S_OK) && pdx.dwResultAction == PD_RESULT_PRINT) 
    {
        // User clicked the Print button, so use the DC and other information returned in the 
        // PRINTDLGEX structure to print the document.
    }

    if (pdx.hDevMode != NULL) 
        GlobalFree(pdx.hDevMode); 
    if (pdx.hDevNames != NULL) 
        GlobalFree(pdx.hDevNames); 
    if (pdx.lpPageRanges != NULL)
        GlobalFree(pPageRanges);

    if (pdx.hDC != NULL) 
        DeleteDC(pdx.hDC);

    return hResult;
}

Menyiapkan Halaman Cetak

Topik ini menjelaskan kode sampel yang menampilkan kotak dialog Penyetelan Halaman sehingga pengguna dapat memilih atribut halaman cetak, seperti tipe kertas, sumber kertas, orientasi halaman, dan margin halaman. Kode sampel pertama kali menginisialisasi struktur PAGESETUPDLG , lalu memanggil fungsi PageSetupDlg untuk menampilkan kotak dialog.

Contoh ini mengatur bendera PSD_MARGINS di anggota Bendera dan menggunakan anggota rtMargin untuk menentukan nilai margin awal. Ini mengatur bendera PSD_INTHOUSANDTHSOFINCHES untuk memastikan bahwa kotak dialog mengekspresikan dimensi margin dalam seperseribu inci.

Pada input, kode sampel mengatur anggota hDevMode dan hDevNames ke NULL. Jika fungsi mengembalikan TRUE, fungsi menggunakan anggota ini untuk mengembalikan handel ke struktur DEVNAMES yang berisi input pengguna dan informasi tentang printer. Anda dapat menggunakan informasi ini untuk menyiapkan output yang akan dikirim ke pencetak terpilih.

Contoh berikut juga memungkinkan prosedur hook PagePaintHook untuk mengkustomisasi gambar konten halaman sampel.

PAGESETUPDLG psd;    // common dialog box structure
HWND hwnd;           // owner window

// Initialize PAGESETUPDLG
ZeroMemory(&psd, sizeof(psd));
psd.lStructSize = sizeof(psd);
psd.hwndOwner   = hwnd;
psd.hDevMode    = NULL; // Don't forget to free or store hDevMode.
psd.hDevNames   = NULL; // Don't forget to free or store hDevNames.
psd.Flags       = PSD_INTHOUSANDTHSOFINCHES | PSD_MARGINS | 
                  PSD_ENABLEPAGEPAINTHOOK; 
psd.rtMargin.top = 1000;
psd.rtMargin.left = 1250;
psd.rtMargin.right = 1250;
psd.rtMargin.bottom = 1000;
psd.lpfnPagePaintHook = PaintHook;

if (PageSetupDlg(&psd)==TRUE)
{
    // check paper size and margin values here.
}

Contoh berikut menunjukkan contoh prosedur hook PagePaintHook yang menggambar persegi margin di area halaman sampel:

BOOL CALLBACK PaintHook(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    LPRECT lprc; 
    COLORREF crMargRect; 
    HDC hdc, hdcOld; 
 
    switch (uMsg) 
    { 
        // Draw the margin rectangle. 
        case WM_PSD_MARGINRECT: 
            hdc = (HDC) wParam; 
            lprc = (LPRECT) lParam; 
 
            // Get the system highlight color. 
            crMargRect = GetSysColor(COLOR_HIGHLIGHT); 
 
            // Create a dash-dot pen of the system highlight color and 
            // select it into the DC of the sample page. 
            hdcOld = SelectObject(hdc, CreatePen(PS_DASHDOT, .5, crMargRect)); 
 
            // Draw the margin rectangle. 
            Rectangle(hdc, lprc->left, lprc->top, lprc->right, lprc->bottom); 
 
            // Restore the previous pen to the DC. 
            SelectObject(hdc, hdcOld); 
            return TRUE; 
 
        default: 
            return FALSE; 
    } 
    return TRUE; 
}

Menemukan Teks

Topik ini menjelaskan kode sampel yang menampilkan dan mengelola kotak dialog Temukan sehingga pengguna dapat menentukan parameter operasi pencarian. Kotak dialog mengirim pesan ke prosedur jendela sehingga Anda bisa melakukan operasi pencarian.

Kode untuk menampilkan dan mengelola kotak dialog Ganti serupa, kecuali menggunakan fungsi ReplaceText untuk menampilkan kotak dialog. Kotak dialog Ganti juga mengirim pesan sebagai respons terhadap klik pengguna pada tombol Ganti dan Ganti Semua .

Untuk menggunakan kotak dialog Temukan atau Ganti , Anda harus melakukan tiga tugas terpisah:

  1. Dapatkan pengidentifikasi pesan untuk pesan terdaftar FINDMSGSTRING .
  2. Tampilkan kotak dialog.
  3. Proses pesan FINDMSGSTRING saat kotak dialog terbuka.

Saat Anda menginisialisasi aplikasi, panggil fungsi RegisterWindowMessage untuk mendapatkan pengidentifikasi pesan untuk pesan terdaftar FINDMSGSTRING .

UINT uFindReplaceMsg;  // message identifier for FINDMSGSTRING 

uFindReplaceMsg = RegisterWindowMessage(FINDMSGSTRING);

Untuk menampilkan kotak dialog Temukan , pertama-tama inisialisasi struktur FINDREPLACE lalu panggil fungsi FindText . Perhatikan bahwa struktur FINDREPLACE dan buffer untuk string pencarian harus menjadi variabel global atau statis sehingga tidak keluar dari cakupan sebelum kotak dialog ditutup. Anda harus mengatur anggota hwndOwner untuk menentukan jendela yang menerima pesan terdaftar. Setelah membuat kotak dialog, Anda bisa memindahkan atau memanipulasinya dengan menggunakan handel yang dikembalikan.

FINDREPLACE fr;       // common dialog box structure
HWND hwnd;            // owner window
CHAR szFindWhat[80];  // buffer receiving string
HWND hdlg = NULL;     // handle to Find dialog box

// Initialize FINDREPLACE
ZeroMemory(&fr, sizeof(fr));
fr.lStructSize = sizeof(fr);
fr.hwndOwner = hwnd;
fr.lpstrFindWhat = szFindWhat;
fr.wFindWhatLen = 80;
fr.Flags = 0;

hdlg = FindText(&fr);

Saat kotak dialog terbuka, perulangan pesan utama Anda harus menyertakan panggilan ke fungsi IsDialogMessage . Teruskan handel ke kotak dialog sebagai parameter dalam panggilan IsDialogMessage . Ini memastikan bahwa kotak dialog memproses pesan keyboard dengan benar.

Untuk memantau pesan yang dikirim dari kotak dialog, prosedur jendela Anda harus memeriksa pesan terdaftar FINDMSGSTRING dan memproses nilai yang diteruskan dalam struktur FINDREPLACE seperti dalam contoh berikut.

LPFINDREPLACE lpfr;

if (message == uFindReplaceMsg)
{ 
    // Get pointer to FINDREPLACE structure from lParam.
    lpfr = (LPFINDREPLACE)lParam;

    // If the FR_DIALOGTERM flag is set, 
    // invalidate the handle that identifies the dialog box. 
    if (lpfr->Flags & FR_DIALOGTERM)
    { 
        hdlg = NULL; 
        return 0; 
    } 

    // If the FR_FINDNEXT flag is set, 
    // call the application-defined search routine
    // to search for the requested string. 
    if (lpfr->Flags & FR_FINDNEXT) 
    {
        SearchFile(lpfr->lpstrFindWhat,
                   (BOOL) (lpfr->Flags & FR_DOWN), 
                   (BOOL) (lpfr->Flags & FR_MATCHCASE)); 
    }

    return 0; 
}