WinAPI 窗口未显示

WinAPI window doesn't appear

本文关键字:显示 窗口 WinAPI      更新时间:2023-10-16

我不知道为什么。我的代码:

#include <windows.h>
#include <commctrl.h>
#include <cstdio>
#include <stdarg.h>
#include <string>
#include <cmath>
#include <vector>
#include "resources.hpp"
using std::string;
using std::vector;
struct undostruct{
    /* add later */};
char buffer[2048];
HWND statusbar;
HINSTANCE hinst;
vector<undostruct> undo;
void show_error(const char* format,...){
    va_list args;
    va_start(args,format);
    vsprintf(buffer,format,args);
    va_end(args);
    MessageBox(NULL,buffer,"ERROR",MB_OK);}
HWND create_tooltip(HWND parent,char* tip,unsigned uid,unsigned extraflags=0){
    HWND tt=CreateWindowEx(WS_EX_TOPMOST,TOOLTIPS_CLASS,NULL,WS_POPUP|TTS_NOPREFIX|TTS_ALWAYSTIP,0,0,0,0,parent,NULL,NULL,NULL);
    SetWindowPos(tt,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
    TOOLINFO ti;
    ti.cbSize=sizeof(TOOLINFO);
    ti.uFlags=TTF_SUBCLASS|extraflags;
    ti.hwnd=parent;
    ti.hinst=NULL;
    ti.uId=uid;
    ti.lpszText=tip;
    GetClientRect(parent,&ti.rect);
    SendMessage(tt,TTM_ADDTOOL,0,(LPARAM)(LPTOOLINFO)&ti);
    return tt;}
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
class Font{
    private:
        HFONT hfont;
    public:
        Font(const char* fname){
            hfont=CreateFont(0,0,0,0,FW_NORMAL,false,false,false,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,fname);}
        ~Font(){
            DeleteObject(hfont);}
        operator HFONT(){
            return hfont;}}courier("Courier New");
bool get_filename(char* fname,int len,HWND hwnd,bool save){
    OPENFILENAME ofn;
    ZeroMemory(&ofn,sizeof(OPENFILENAME));
    ofn.lStructSize=sizeof(OPENFILENAME);
    ofn.hwndOwner=hwnd;
    ofn.lpstrFilter="Text Files (*.txt)*.txtAll Files (*.*)*.*";
    ofn.lpstrFile=fname;
    ofn.nMaxFile=len;
    ofn.lpstrTitle="Text Editor";
    ofn.Flags=OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
    if(save){
        return GetSaveFileName(&ofn);}
    else{
        return GetOpenFileName(&ofn);}}
int WINAPI WinMain(HINSTANCE hprev,HINSTANCE hInst,LPSTR cmdline,int cmdshow){
    WNDCLASSEX wcex;
    //HACCEL haccel=LoadAccelerators(hInst,MAKEINTRESOURCE(ACCELS));
    HWND hwnd;
    MSG msg;
    hinst=hInst;
    //Register the window
    wcex.cbSize=sizeof(WNDCLASSEX);
    wcex.style=CS_HREDRAW|CS_VREDRAW;
    wcex.lpfnWndProc=WndProc;
    wcex.cbClsExtra=0;
    wcex.cbWndExtra=0;
    wcex.hInstance=hinst;
    wcex.hIcon=NULL;
    wcex.hCursor=NULL;
    wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName=MAKEINTRESOURCE(MAINMENU);
    wcex.lpszClassName="ImageEditor";
    wcex.hIconSm=NULL;
    if(!RegisterClassEx(&wcex)){
        show_error("Error %i: Failed to register the window.",GetLastError());
        return -1;}
    //Create the window
    hwnd=CreateWindow("ImageEditor","Image Editor",WS_VISIBLE|WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hinst,NULL);
    if(!hwnd){
        show_error("Error %i: Failed to create the window.",GetLastError());
        return -2;}
    //Show/Update the window
    ShowWindow(hwnd,cmdshow);
    UpdateWindow(hwnd);
    //Initialize common controls
    /*INITCOMMONCONTROLSEX iccex;
    iccex.dwICC=ICC_WIN95_CLASSES;
    iccex.dwSize=sizeof(INITCOMMONCONTROLSEX);
    InitCommonControlsEx(&iccex);*/
    //Go into the main program loop
    while(GetMessage(&msg,NULL,0,0)){
        //if(!TranslateAccelerator(hwnd,haccel,&msg)){
            TranslateMessage(&msg);
            DispatchMessage(&msg);}//}
    return msg.wParam;}
LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){
    static int sizes[]={260,330,420,520};
    switch(msg){
        case WM_CREATE:
            statusbar=CreateWindow(STATUSCLASSNAME,"",WS_CHILD|WS_BORDER|WS_VISIBLE,-100,-100,10,10,hwnd,NULL,hinst,NULL);
            if(!statusbar){
                show_error("Error %i: Failed to create the statusbar.",GetLastError());}
            //Description|Characters|Size|Lines|Line|Column
            SendMessage(statusbar,SB_SETPARTS,sizeof(sizes),(LPARAM)sizes);
            break;
        case WM_QUIT:
            DestroyWindow(hwnd);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_COMMAND:
            //switch(LOWORD(wparam)){}
            //break;
        default:
            return DefWindowProc(hwnd,msg,wparam,lparam);}
    return 0;}

此外,我的编译器在应该识别INITCOMONCONTROLSEX的时候没有识别它,这在WinMain的末尾被注释掉了。

此代码中最有可能的错误是在创建窗口之前需要运行InitCommonControls。忘记InitCommonControlsEx()代码,使用普通的旧InitCommon\Controls会更好。

请记住检查每个函数的返回值并使用GetLastError()。

此外,你正在尝试重新发明轮子,我建议你看看别人是如何做到的,甚至使用WTL,而不是推出自己的窗口创建程序,这并没有那么难。