Ir ao conteúdo
  • Cadastre-se

C Fechar a console aplicação Windows API


Lucca Rodrigues

Posts recomendados

No meu notebook antigo que tinha Windows 8, a console fechava normalmente com o código abaixo. Windows 7 e 10 também funciona.

HWND hWnd = GetConsoleWindow();
PostMessage(hWnd, WM_CLOSE, 0, 0);

Recentemente adquiri um notebook com Windows 11, e nada que eu uso faz a console fechar, o que me leva a pensar se não seria alguma configuração.

image.thumb.png.dd7f04bec4507573748b0fcd9e160718.png

image.thumb.png.18a25049fd4848ae02fddb06496f6d31.png

ShowWindow(hWnd, SW_HIDE) também não funciona, só consigo usar ShowWindow(hWnd, SW_MINIMIZE) e somente depois de passados uns 2 segundos da inicialização do aplicativo (coloquei no meio de um segmento de código pro caso WM_TIMER), antes disso, ele não minimiza.

Achei muito estranho, alguém sabe que diabos tá acontecendo?

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Não entendi exatamente qual seria seu problema,
como você abriu o console, ou se ele está abrindo
automaticamente, como criou o projeto, que IDE
está usando, porque nos meus projetos de
Win32 no VS Studio 2022, eu preciso de alguns
códigos para forçá-lo abrir junto com a janela,
e muitas vezes faço isto para imprimir valores
de variáveis, em determinados pontos.
Então por aqui eu abri o console junto com a janela
e fechei normalmente usando seu trecho de código,
os códigos foram inseridos nos eventos de dois botões,
onde um abriu o console e o outro fechou naturalmente.

Também estou usando Windows 11 igual você.

 

        case IDC_BUTTON3:
            Beep ( 500, 500 );
            static HANDLE out;  // This can be part of the class
            // This can be part of the application initialization
            if ( AllocConsole ( ) ) {
                out = GetStdHandle ( STD_OUTPUT_HANDLE );
            }
            break;
        case IDC_BUTTON4:
            Beep ( 1500, 500 );
            PostMessage ( hwnd, WM_CLOSE, 0, 0 );
            break;
        }
        break;

 

 

 

  • Amei 1
Link para o comentário
Compartilhar em outros sites

@Lucca Rodrigues      você quer fechar a janela do console ou  a janela da aplicação ? ,   pois o janela da aplicação você pode fechar usando esse comando

case WM_DESTROY:
  PostQuitMessage (0);

e a do console use esse se estiver usando o codeblocks

system("taskkill /IM cb_console_runner.exe"); // no codeblocks

e esse no Visual Studio

VsDebugConsole.exe

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Em 20/01/2023 às 18:32, Lucca Rodrigues disse:
HWND hWnd = GetConsoleWindow();
PostMessage(hWnd, WM_CLOSE, 0, 0);

 

Em 20/01/2023 às 18:32, Lucca Rodrigues disse:

No meu notebook antigo que tinha Windows 8, a console fechava normalmente com o código abaixo. Windows 7 e 10 também funciona.

 

Até entendo que feche, mas é algo nebuloso.  Você consegue um Handle para uma janela e manda uma mensagem. O que acontece depois depende dos privilégios de sua aplicação em relação à janela.

O Handle pode ser inválido. Você pode não ter privilégios para fechar tal janela, tem a ver com os Security Descriptors ou algo assim.

 

A janela da console não é do seu programa. Não era pra fechar. Uma janela da console é a versão Windows de um /dev/tty. Não está claro que um processo de usuário possa fechar uma janela de console. A menos que o próprio processo a tenha criado.  O mesmo vale para o Terminal do windows. Quem é o processo para fechar uma janela que não foi ele que abriu?

 

4 horas atrás, devair1010 disse:
case WM_DESTROY:
  PostQuitMessage (0);

 

Pois é: WM_DESTROY vai destruir o processo. E por consequência fechar janelas que ele tenha criado. Só que provavelmente nesse caso não criou tal janela. 

 

4 horas atrás, devair1010 disse:

e a do console use esse se estiver usando o codeblocks

system("taskkill /IM cb_console_runner.exe"); // no codeblocks

e esse no Visual Studio

VsDebugConsole.exe

 

system() só vai passar esse comando adiante. E vai depender dos privilégios da aplicação o que acontece a seguir. E interferir no comportamento das janelas do IDE --- sim, IDE é masculino, de ambiente --- é algo folclórico. Isso é pedir por problemas. O IDE não tem controle sobre isso então pode se perder. Em Visual Studio não é raro ter que reiniciar o IDE ou mesmo a máquina depois de rodar sessões de teste de programas de console que mexem com a janela de console ou mesmo abrem outras consoles.

 

Rodar programas de console na janela de teste do IDE é algo conveniente mas nada, NADA mesmo tem a ver com o uso do programa. Apenas no mundo dos estudantes e iniciantes a vida do programa termina quando ele fica pronto. No mundo normal a vida dele COMEÇA quando ele fica pronto e é vendido, distribuído, instalado. Entra em produção.

 

Imagine que a sessão do Terminal ou do CMD está lá aberta para rodar comandos. E você testa seus 8 programas na console, a seu critério. Um que cria um arquivo de dados a partir de dados coletados por sensores por exemplo. E outros que fazem contas a partir disso. Qual será sua reação se um desses infelizes fechar a janela da console?

 

O usuário que rodou o programa pode simplesmente querer rodar comandos, uns DEL para apagar arquivos de teste, rodar outro programa, rodar um ping, rodar um shutdown. . . E fechar a janela é algo exagerado. O programa que roda no Terminal não é o dono do terminal. Ou da console.

 

Um caso limite é quando você roda seu programa a partir por exemplo do comando executar do Windows. Win+R. Nesse caso o sistema deve criar um ambiente para rodar o programa e pelo próprio executável o sistema sabe que é um programa de console. Por isso por exemplo existe o /SubSystem:CONSOLE no LINK.

 

Então o SISTEMA sabe que a janela foi criada apenas para rodar esse programa e ele deve fechar a janela como parte do encerramento do  processo. Não o seu programa.

 

Fechar a janela é um inconveniente e não uma boa coisa. 

 

@Lucca Rodrigues poste algo compilável, completo. É melhor para quem quiser ajudar.

 

 

 

 

 

 

 

Em 20/01/2023 às 18:32, Lucca Rodrigues disse:

a console fechava normalmente

 

Então, concluindo: não acho nada normal fechar a console. Não sei dizer do comportamento em diversas versões de Windows porque nunca me ocorreu programar algo assim: um programa de console é só um usuário da console. Como em Unix era um usuário do terminal. Fechar o terminal encerraria a sessão do usuário como um todo por exemplo.

 

A menos que algum recurso paranormal não vejo como um programa saber o que o usuário da console vai querer fazer a seguir, e o normal é deixar tudo como achou.

 

Se a janela foi aberta para rodar o programa o sistema vai saber o que fazer. CMD /C e CMD /K por exemplo tem comportamentos distintos. Win+R também.

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Em 31/01/2023 às 12:49, arfneto disse:

poste algo compilável, completo. É melhor para quem quiser ajudar.

Pior que nem dá, são 4000 linhas de código, e depende de vários arquivos.

Em 31/01/2023 às 12:49, arfneto disse:

Então, concluindo: não acho nada normal fechar a console.

Então, mas isso é algo que eu observo as vezes: minimizar, esconder, fechar, etc. A não ser que não seja exatamente isso que ocorre.

Por exemplo, esse gif da inicialização do matlab aqui no meu computador:

ezgif-2-9359e13a01.gif.be51975b0fb9fd19768758ba7019fc9b.gif

A questão é justamente essa, o usuário não vai fazer nada na console, então o esperado é que ela fique escondida após a inicialização e seja fechada quando o programa for encerrado, sem que o usuário precise fechar manualmente.

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

2 horas atrás, Lucca Rodrigues disse:

Pior que nem dá, são 4000 linhas de código, e depende de vários arquivos.

 

Esse é o ponto do "exemplo mínimo, completo e verificável"  repetido à exaustão no (pedante) site do stack overflow.

 

E a dificuldade em conseguir isso pode mostrar algum outro problema: o design do produto em si. Em teoria se deve escrever qualquer programa como uma biblioteca. Ou várias. E assim extrair um mínimo para uma função main() de duas linhas mostrar o problema ou isolar algo que está testando deve ser algo simples.

Por outro programas com 4000 linhas nem são grandes hoje em dia então entendo a dificuldade.

Lembre que pode sempre deixar um link para o projeto no github, que é um caminho comum hoje em dia para o desenvolvimento de projetos, Open Source ou não.

 

2 horas atrás, Lucca Rodrigues disse:

Então, mas isso é algo que eu observo as vezes: minimizar, esconder, fechar, etc. A não ser que não seja exatamente isso que ocorre

 

Não entendi o que significa.

 

2 horas atrás, Lucca Rodrigues disse:

gif da inicialização do matlab aqui no meu computador

 

Isso é chamado de splash screen em geral. Não está claro que a imagem seja um gif. E isso pode indicar que MATLAB está sendo carregado como um serviço ou ser apenas propaganda mesmo, disparado por algo na carga do sistema ou da sessão. E não é necessariamente um programa de console.

 

2 horas atrás, Lucca Rodrigues disse:

A questão é justamente essa, o usuário não vai fazer nada na console, então o esperado é que ela fique escondida após a inicialização e seja fechada quando o programa for encerrado, sem que o usuário precise fechar manualmente

 

Bem... Não é. Imagine um programa x.exe em c:\temp numa máquina Windows.

 

Se você escreveu isso e acha que o " esperado" é ela ficar "escondida" e depois "fechada" é porque você escreveu o programa e está determinando como alguém vai usar isso. Até onde o sistema sabe é apenas um arquivo e possivelmente de código.

 

Considere:

  • Décadas atrás quando o cara escrevia um programa (para Unix) não existia programa de console. Na verdade ou o programa era de console ou era algo chamado "daemon". Só existiam programas de console. deamons eram programas que não eram associados necessariamente a nenhuma console, o equivalente a serviços no Windows hoje. Claro que não podia fechar a console em nenhum dos casos. Se fosse rodar em um mainframe não seria interativo então também nem teria esse conceito.
  • Se hoje o usuário tem uma console aberta pode rodar seu programa usando o nome completo dele e teclando ENTER. Se o programa fechar ou ao menos tentar fechar a janela da console isso será algo intrusivo e acho que nunca entraria em produção uma coisa dessas. E se o cara quiser rodar um programa logo depois --- como te expliquei --- para um serviço adicional? Consultar um log? Testar os resultados? O usuário vai ficar furioso por seu programa ter fechado a console que não foi ele que abriu. 
    • E se fosse em uma sessão remota? O cara ia ter que se conectar de novo e ia pedir a sua cabeça.
    • E se fosse dentro de um contexto de mais de uma VPN e conexão? O cara iria pessoalmente atentar contra sua vida 😉 
  • Se rodar o seu programa via por exemplo Win+R e o nome dele faz todo sentido fechar a janela, porque está óbvio o fato de que ela foi aberta para rodar o seu programa. E o sistema faz isso.
  • Se rodar dentro de um script(batch file)  via CMD /K ou /C por exemplo é outra coisa que você deve considerar.
  • Mais ainda: hoje os sistemas são multi-usuário, os programas podem ter várias threads, o sistema pode ter mais de um usuário com sessão aberta, a janela que roda seu programa pode nem estar visível. Há muito que considerar.
  • Seu programa pode ser rodado numa janela de terminal do Windows e é mais complicado de DENTRO de seu programa saber como ele foi ativado.
  • De dentro do IDE nada disso faz sentido porque a última coisa que deve fazer é tentar controlar as janelas do IDE que não foi você que escreveu. Pode (e vai muitas vezes) comprometer a estabilidade do próprio IDE.
  • Se tem uso real mesmo para isso, como uma splash screen, crie a janela dentro de seu programa

 

 

 

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@arfneto Se quiser pode testar isso, mas te garanto que o problema não é o código:

#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR lpCmdLine, INT nCmdShow) {

    MSG  msg;
    WNDCLASSW wc = {0};
    wc.lpszClassName = L"Static Control";
    wc.hInstance     = hInstance;
    wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
    wc.lpfnWndProc   = WndProc;
    wc.hCursor       = LoadCursor(0, IDC_ARROW);


    RegisterClassW(&wc);
    CreateWindowW(wc.lpszClassName, L"Exemplo",
                  WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                  100, 100, 300, 300, 0, 0, hInstance, 0);

    while (GetMessage(&msg, NULL, 0, 0)) {

        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,
    WPARAM wParam, LPARAM lParam) {

    static wchar_t *texto =  L"Feche essa janela";

    switch(msg) {

        case WM_CREATE:
            CreateWindowW(L"Static", texto,
                WS_CHILD | WS_VISIBLE | SS_LEFT,
                20, 20, 300, 230,
                hwnd, (HMENU) 1, NULL, NULL);
            break;

        case WM_CLOSE:
            DestroyWindow(hwnd);
            break;

        case WM_DESTROY:
            PostQuitMessage(0);
            PostMessage(GetConsoleWindow(), WM_CLOSE, 0, 0);
            break;
    }

    return DefWindowProcW(hwnd, msg, wParam, lParam);
}

 

35 minutos atrás, arfneto disse:

Isso é chamado de splash screen em geral. Não está claro que a imagem seja um gif. E isso pode indicar que MATLAB está sendo carregado como um serviço ou ser apenas propaganda mesmo, disparado por algo na carga do sistema ou da sessão. E não é necessariamente um programa de console.

gif que eu digo é a imagem que eu postei, aqui no clube do hardware não dá pra postar vídeo.

Não sei se deu pra ver bem no gif, mas antes da splash screen, isso aparece e desaparece:
image.thumb.png.9387e4a1a3632becfbab9b5030b30ad8.png
 

35 minutos atrás, arfneto disse:

Se você escreveu isso e acha que o " esperado" é ela ficar "escondida" e depois "fechada" é porque você escreveu o programa e está determinando como alguém vai usar isso. Até onde o sistema sabe é apenas um arquivo e possivelmente de código.

O esperado que eu digo é o que se espera como usuário, pois nesse exemplo do matlab, se esse terminal que apareceu ficasse ali, eu acharia estranho. Mais estranho ainda se eu tivesse que fechar manualmente depois de encerrar o matlab.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

8 minutos atrás, Lucca Rodrigues disse:

Se quiser pode testar isso, mas te garanto que o problema não é o código

 

Vou ver depois. Mas acho que entendeu o que eu acho e as razões que eu te dei: problema é fechar a janela. Não é razoável fechar a janela que não foi seu programa que abriu. 

 

A janela da console não é de se seu programa. O sistema é que deve cuidar disso. 

 

image.png.9c182e7f58d8fb92e6dfbc82a09cf50c.png

 

Nesse caso deve fechar...

 

 

 

Mas e nesse:

 

image.png.1d62b094b5c5814db25fd11465864a47.png

Quem garante que a console só foi aberta para rodar isso?

 

 

 

14 minutos atrás, Lucca Rodrigues disse:

O esperado que eu digo é o que se espera como usuário, pois nesse exemplo do matlab, se esse terminal que apareceu ficasse ali, eu acharia estranho. Mais estranho ainda se eu tivesse que fechar manualmente depois de encerrar o matlab

 

Pois é: você está falando duas vezes de uma splash screen da carga do MATLAB. O sistema não sabe o que é o programa. Seria estranho se um programa qualquer que eu mandei rodar fechasse a minha console TODA vez. Imagine o gcc por exemplo...

 

 

 

 

Se você precisa de uma splash screen abra uma janela e crie uma.

 

Ou não entendi mesmo o problema...

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Em 02/02/2023 às 15:59, Lucca Rodrigues disse:

esse gif da inicialização do matlab aqui no meu computador

 

Pode até ficar sem essa janelinha intrusiva usando -nosplash na carga no programa

 

image.png.193fb62fbd5c123f1c8fcc6be6e49586.png

 

mas de qualquer modo 

 

Em 02/02/2023 às 19:16, Lucca Rodrigues disse:

Se quiser pode testar isso, mas te garanto que o problema não é o código

 

por certo o problema não seria esse código.

 

Isso que postou não é uma aplicação para console. Deve ser gerada com

 

	Link /SUBSYSTEM:Windows

 

E não vi diferença entre rodar isso em Windows 10 ou 11. 

 

Acho que não entendi o problema.

 

 

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

2 minutos atrás, arfneto disse:

Isso que postou não é uma aplicação para console

É para desktop. Quando você fechou a janela, a console fechou também? pra mim não fecha, tenho que fechar manualmente pra toda aplicação com a api do windows pra desktop.

 

4 minutos atrás, arfneto disse:

Pode até ficar sem essa janelinha intrusiva usando -nosplash na carga no programa

O que eu estava falando é do terminal.

Em 02/02/2023 às 19:16, Lucca Rodrigues disse:

nesse exemplo do matlab, se esse terminal que apareceu ficasse ali, eu acharia estranho. Mais estranho ainda se eu tivesse que fechar manualmente depois de encerrar o matlab.

Aparece um terminal, some e depois aparece a splash screen.

ezgif-2-9359e13a01.gif.be51975b0fb9fd19768758ba7019fc9b.gif.350ee663405fb2e5715a67e5f74adadf.gif

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

4 horas atrás, Lucca Rodrigues disse:

É para desktop. Quando você fechou a janela, a console fechou também? pra mim não fecha, tenho que fechar manualmente pra toda aplicação com a api do windows pra desktop.

 

Ainda não sei se estamos falando da mesma coisa. Imagino que tenha lido os exemplos que te mostrei e os argumentos que expliquei. Não sei o que seria 

 

Em 20/01/2023 às 18:32, Lucca Rodrigues disse:

a console fechava normalmente com o código abaixo

 

que era uma mensagem WM_CLOSE para a janela. Não acho que seria normal fechar. Acho que seria algo pouco inteligente e muito intrusivo, ainda que o programa chamado tivesse privilégios para tal. E te expliquei porque.

 

4 horas atrás, Lucca Rodrigues disse:

O que eu estava falando é do terminal.

 

Eu sei. E estava claro isso. O que eu queria dizer e não ficou claro --- me desculpe --- é que seria muito mais razoável alguém não querer mostrar aquela janelinha bobinha no caso do MATLAB toda vez que abre o programa. E os caras sabem disso e por isso existe a opção -nosplash. Mas daí a fechar a console que não foi o programa MATLAB que abriu é outra história.

 

Ao final da sessão do MATLAB a console fecha. Se era um serviço a ser carregado a janela fecha ao final do serviço. Só isso.

 

EXEMPLO

 

notepad3x.jpg.da315b2e5dbcae1ad47e79b6c01efc7a.jpg

 

 

Veja essa tela: tinha uma console aberta. E podia ser um terminal. E aí o usuário, que é o DONO da sessão, rodou essas 3 sessões do NOTEPAD e aí abriu as 3 janelas. 

 

Você acha mesmo que seria normal ter que abrir 3 janelas para fazer isso?

 

Imagine se o gcc fechasse a sessão da console a cada vez que mandasse compilar um programa. 

 

E se fosse uma sessão do CMAKE para atualizar um projeto de 800 arquivos? Ia levar uma semana se fosse alocar uma nova console para cada sessão de compilação. E o contexto? Os diretórios podem ir mudando durante as compilações. Teria que ir reiniciando tudo?

 

Mesmo no caso do MATLAB. Se ao final da sessão for rodar um programa de análise dos dados vai precisar abrir outra sessão? Voltar para o diretório certo já poderia ser um problema.

 

4 horas atrás, Lucca Rodrigues disse:

Aparece um terminal, some e depois aparece a splash screen

 

É o esperado, quando esperado. Então rode o programa a partir do menu executar --- Win+R --- ou um atalho no desktop. Ou via CMD /K ou /C. A janela vai fechar porque foi aberta para rodar o programa. 

 

Um programa fechar a janela da console que não foi ele que abriu não é razoável. E se tiver 4 consoles e 4 sessões de terminal no Windows? Podia fechar todos se sua conta tiver privilégios suficientes. Daí a fazer isso é outra coisa. 

 

É como encerrar a sessão. Ou rodar um shutdown. Muitos programas podem fazer isso. Daí a fazer é outro caso.

 

Ainda não entendi o que pode ter mudado do Windows 7 para o 11. Ou mesmo do Windows 3 para o 11 (No Windows 3 só tinha uma console, de certo modo).

 

 

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@Lucca Rodrigues @Lucca Rodrigues      entendi , que ,  sobre o Matlab , você está apenas dando um exemplo do que você quer fazer em um  projeto da API do Windows , que cria uma janela e ela fica sobre a console , e quando você clicar no  "X" no canto dessa janela criada pela  API  do Windows , ele fecha , e em alguns casos a janela da console continua aberta , e aí então você precisa clicar no "X " no canto dessa janela da console para fechar ela manualmente , e o que você  quer é que quando rodar esse projeto , ele vai criar a janela do projeto e minimizar a janela da console , e quando clicar para fechar a janela criada , fechar também a janela da console ,  como nesse vídeo .

 

https://www.youtube.com/watch?v=OIJlXf7tdVc

 

que sem esse comando :que nesse case está comentado , não fecha a console ao fechar a janela da aplicação :

case WM_DESTROY:
  PostQuitMessage(0);
  /// esse comando fecha a janela da conbsole
  /// PostMessage(GetConsoleWindow(), WM_CLOSE, 0, 0); 
  /// junto com a janela da aplicaCao criada pela API do Windows
  break;                                                


e  precisa fechar manualmente a console ,  e no vídeo ,  na segunda vez que excuta o programa , e dessa vez usando esse comando : , pois dessa vez ele não está comentado  , 

PostMessage(GetConsoleWindow(), WM_CLOSE, 0, 0);  /// esse comando fecha a janela da conbsole


a janela da Aplicação e a da console são fechadas ao mesmo tempo .   aqui no Windows 10  .

 

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!