Ir ao conteúdo
  • Cadastre-se

C criar Gráficos no Visual Studio


devair1010
Ir à solução Resolvido por Flávio Pedroza,

Posts recomendados

    olá , pessoal  , consegui instalar o visual studio 2019 , e apesar de ele precisar muito espaço no ssd ,  ele está funcionando bem , e estou tentando criar um gráfico , para testar , e está dando erro que não estou sabendo como resolver ,  agradeço quem puder me ajudar   .

  esse código aqui :

// graficos testar_1.cpp : Este arquivo contém a função 'main'. A execução do programa começa e termina ali.
//

#include <iostream>

int main()
{
    HWND hw;
    HDC dc; 
    hw = GetConsoleWindow();
    dc = GetDC(hw);
    COLORREF cor = RGB(255,255,0);
    int i;
    std::cout << "Hello World!\n";
    for (i = 0; i < 1000; i++)
    {
        SetPixel(dc, i, cos(i*3.141592/180) * 100 + 250, cor);
        Sleep(5);
    }
    return 8;
}

// Executar programa: Ctrl + F5 ou Menu Depurar > Iniciar Sem Depuração
// Depurar programa: F5 ou menu Depurar > Iniciar Depuração

// Dicas para Começar: 
//   1. Use a janela do Gerenciador de Soluções para adicionar/gerenciar arquivos
//   2. Use a janela do Team Explorer para conectar-se ao controle do código-fonte
//   3. Use a janela de Saída para ver mensagens de saída do build e outras mensagens
//   4. Use a janela Lista de Erros para exibir erros
//   5. Ir Para o Projeto > Adicionar Novo Item para criar novos arquivos de código, ou Projeto > Adicionar Item Existente para adicionar arquivos de código existentes ao projeto
//   6. No futuro, para abrir este projeto novamente, vá para Arquivo > Abrir > Projeto e selecione o arquivo. sln

 

Link para o comentário
Compartilhar em outros sites

  • Solução

O que você quer fazer não vai funcionar, não há como desenhar no console.

você tem que criar um aplicativo Win32 (Winmain) e criar uma janela com CreateWindowsEx.

Quando for criar um projeto, escolha a opção "Aplicativo do Windows Desktop".

 

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

@Flávio Pedroza   obrigado por ajudar ,  mas você usa o visual studio  da MicroSoft ?  ,  aqui nele não encontrei essa opção , apenas uma parecida  :

1897583482_assistentedowindowsdesktop.jpg.21e7683f5c6c54089c5864da028ba447.jpg

 

mas usei mesmo a opção Aplicativo de console . que está acima dessa ,

 

@Midori    boa ideia ,  coloquei essa biblioteca  windows.h , e funcionou bem , e formou o Gráfico certinho :

 

1230748466_graficosnovisualstudio.thumb.jpg.e64e777a04c8399d0062c07487289d29.jpg

 

obrigado pela ajuda .

Link para o comentário
Compartilhar em outros sites

16 minutos atrás, devair1010 disse:

boa ideia ,  coloquei essa biblioteca  windows.h , e funcionou bem , e formou o Gráfico certinho

 

É windowS, no plural. E a console é uma janela só. Não é que funcionou certinho, apenas funciona. Não vai muito longe com isso. A console é compartilhada pelos programas que rodam no terminal. Sem muito trabalho nem pode abrir mais janelas no seu programa, o que é algo estranho porque afinal Windows é plural então devia poder abrir várias janelas. E tem os componentes do Windows, os tais controles, botões, labels, checkboxes, aquelas coisas. A comunicação entre esses controles não funciona bem nesse ambiente. O LINK vai dar problema, bibliotecaqs não vão funcionar...

 

A console é um animal estranho no Windows, como a janela gráfica é um animal estranho no Unix/Linux

 

Se você não vê o tipos de projeto que quer talvez deva rodar o installer de novo, basta apertar a tecla do Windows e digitar Visual Studio Installer, só as primeiras letras. Ou no próprio menu de criar projeto tem um link. Algo assim:

image.png.832c3b9aed4ae2648560d5f274c67716.png

 

veja o link em azul: vai dar na mesma que abrir o Installer: o link vai chamar o installer. Visual Studio é um ecossistema. Tem muitas linguagens e ambientes. Veja por exemplo na máquina que estou usando, se escolher a linguagem
 

image.png.1b0767990e6695a634a0c6d160f1fef9.png

 

C++ E Windows

 

image.png.a02c81652df926a9bda6b6122d3d4b0a.png

image.png.0fdcebbf593c3267c502bd66f4668e79.png

Aí vem a lista dos "alvos" e tem lá console e Desktop e outros. O que aparece depende de como está instalado. Isso pode ir de uma instalação simples de umas centenas de megabytes até dezenas de Gigabytes. Mais as extensões. E os componentes de suporte do Windows. E os pacotes.

 

Como eu disse, é um ecossistema. O mundo inteiro usa isso, para projetos pequenos ou gigantes. O BRADESCO usa, a NASA usa, a JPL usa, as escolas usam. Cada um de um jeito.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Veja uma tela em português do instalador parada logo no início, em "Web e Nuvem" 
 

image.thumb.png.51f1126e8f764b973c438788245a11ee.png

 

Na sua máquina clique no botão enorme de C++ e veja o que aparece no formulário a direita. Depois confirme qualquer eventual modificação e tecla ENTER e pronto.

Se vai mesmo usar essas coisas de gráfico em C++ --- e em geral não é uma boa ideia --- instale o vcpkg, o gerenciador de pacotes da Microsoft, que agora está integrado ao Visual Studio e é open source, e o CMake. Assim poderá instalar os frameworks modernos para gráficos em um clique só. 

Os frameworks importantes de games estão direto no installer, nas telas seguintes, como Unity e Unreal

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

19 minutos atrás, devair1010 disse:

 instalei o visual studio junto com as linguagens , c  c++    c#  e  javascript, e ocupou 10 gigabytes da unidade c , 

 

Se está contando o espaço com o explorer não vai funcionar. E veja que na figura que mostrou são apenas 10MB no C...

O espaço aparece no installer apenas. E arquivos vão para todo lado. E tem os pacotes. Cada framework pode levar mais alguns GB. Cada um.

 

Na máquina que estou usando agora acho que ocupa menos de 20, um pouco mais com alguns pacotes.

 

24 minutos atrás, devair1010 disse:

e esse Gráfico se desmancha Quando movimento a janela da console

 

Faz sentido. Como eu disse, essa janela é bem diferente das outras. 

Vendo as pastas mais conhecidas acho que na máquina que estou usando agora tem 14.8GB em quase 100.000 arquivos. E a pasta repos tinha um tamanho absurdo até outro dia. Escrevi até um aplicativo para fazer uma analise nessas pastas e apagar coisas, em julho eu acho.

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

@arfneto      isso mesmo , confundi com  visual studio 2005 ,  

 

368212659_tamanhovs_2.jpg.0cd492c7762e7c7dd241b6ce886e7be2.jpg

 

e realmente não consigo encontrar todas as partes do visual studio , para saber o quanto ele ocupa , mas na hora da instalação , a unidade  c  do ssd estava com 10 GB livres e mesmo instalando na unidade D , que tinha 150 GB livres ,  não deu para instalar , precisei deletar alguns arquivos para conseguir instalar ,  pois o installer dizia que precisava mais espaço na unidade  c ;

Link para o comentário
Compartilhar em outros sites

Sobre o seu programa:

 

Eu não tinha prestado atenção ao código :( desculpe
 

int main()
{
    HWND hw;
    HDC dc; 
    hw = GetConsoleWindow();
    dc = GetDC(hw);
    COLORREF cor = RGB(255,255,0);

 

Essa chamada a GetConsoleWindow() não vai funcionar em um aplicativo tradicional. Eu rodei aqui com o projeto de desktop, apenas mudei 2 coisas:

 

        SetPixel(dc, i, (int)( cos(i * 3.141592 / 180) * 100. + 250.), cor);

 

Para fazer as contas em double antes de converter, e em Linker | System mudei para SUBSYSTEM:CONSOLE para aceitar a chamada a GetConsoleWindow().

Se quer usar o modo normal  chame CreateWindowEx() para criar uma janela e passe o HANDLE dela para GetDC() no lugar desse que recebeu de GetConsoleWindow().

 

Claro que pode usar a mesma janela do menu e usar o seu código dentro de WM_PAINT que é a mensagem que atualiza a tela, e aí pode usar o programa normal como gerado pelo Visual Studio, e colocar seu código assim lá dentro
 

    case WM_PAINT:
        {
            PAINTSTRUCT ps;

            HDC hdc = BeginPaint(hWnd, &ps);
            HDC dc = GetDC(hWnd);
            COLORREF cor = RGB(255, 0, 0);
            for (int x = 0; x < 1000; x++)
            {
                int y = (int)(cos(x * 3.141592 / 180) * 100. + 250.);
                SetPixel(dc, x, y, cor);
                Sleep(5);
            }   // for()

            EndPaint(hWnd, &ps);
        }
        break;

 

E sem mexer nas opções de LINK. Seria melhor usar um traço mais grosso e escolher uma cor a partir das cores em uso na janela. Para traçar o gráfico em toda a janela veja acho que em GetSystemMetrics() o tamanho da janela e ajuste o limite do x no loop

🤔  GetSystemMetrics() vai trazer as métricas das telas todas. Foi mal. Só precisa saber da sua janela  hWnd então pode usar esse trecho que desenha o gráfico até o fim da janela
 

            PAINTSTRUCT ps;
            GetWindowInfo(hWnd, &wInfo);
            HDC hdc = BeginPaint(hWnd, &ps);
            HDC dc = GetDC(hWnd);
            COLORREF cor = RGB(255, 0, 0);
            for (int x = 0; x < (wInfo.rcClient.right - wInfo.rcClient.left); x++)
            {
                int y = (int)(cos(x * 3.141592 / 180) * 100. + 250.);
                SetPixel(dc, x, y, cor);
                Sleep(5);
            }   // for()

            EndPaint(hWnd, &ps);

 

Mudei para (x,y) só para ficar mais fácil de ler :) 

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

9 minutos atrás, devair1010 disse:

@Flávio Pedroza    ok , usei essa e funciona , mas os comandos são bem diferentes da linguagem c da console , printf não funciona , é outra linguagem . ou pelo menos comandos pouco divulgados .    mas obrigado , ajudou muito .

Então, é para irá desenvolver um aplicativo Windows, sem console. Deve usar a API do Windows para desenhar na tela.

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


Para encaixar certinho o gráfico na tela use essa conta
 

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            GetWindowInfo(hWnd, &wInfo);
            int H = wInfo.rcClient.bottom - wInfo.rcClient.top;
            int W = wInfo.rcClient.right - wInfo.rcClient.left;

            HDC hdc = BeginPaint(hWnd, &ps);
            HDC dc = GetDC(hWnd);
            COLORREF cor = RGB(0, 0, 255); // azul
            for (int x = 0; x < W; x+=1)
            {
                int y = (int)(cos(x * 3.141592 / 180) * H/2. + H/2.);
                SetPixel(dc, x, (int)y, cor);
                Sleep(5);
            }   // for()
            EndPaint(hWnd, &ps);
        }
        break;

 

Em geral (x,y) são usados para as coordenadas e H e W são a altura e a largura da janela. Se o usuário muda o tamanho da janela vem na mensagem e o loop recalcula então sempre fica encaixado na altura e na largura. Nã pode usar constantes.

 

1 hora atrás, devair1010 disse:

printf não funciona , é outra linguagem

 

a bem da verdade printf() é mesmo de outra linguagem e vem de stdio.h do C. E cout, cerr e cin do C++ aqui não funcionam porque não dá para acessar streams assim em um programa para desktop. 

 

Se quer usar texto use uma caixa de texto como aqui no forum. Ou Edit boxes, botões, labels, listas, essas coisas. São chamados controles e C, C++ e a API do windows não são bons caminhos para escrever isso. Claro que funciona, mas não compensa o trabalho.

 

A filosofia é simples: você cria os controles. Eles geram mensagens conforme seu programa roda. E você trata essas mensagens naquele switch(message) em WndProc().

 

Quer escrever algo? Crie um controle. Um RichEdit por exemplo permite que o usuário entre e edite texto na janela.

 

Para um número enorme de exemplos veja em https://github.com/microsoft/Windows-classic-samples/blob/1d363ff4bd17d8e20415b92e2ee989d615cc0d91/Samples/Win7Samples/netds/winsock/ipxchat/IpxChat.c

 

Em C++ agora se pode usar std::numbers::pi para, bem, PI. 

 

    int i;
    std::cout << "Hello World!\n";
    for (i = 0; i < 1000; i++)
    {
        SetPixel(dc, i, cos(i*3.141592/180) * 100 + 250, cor);
        Sleep(5);
    }

 

Evite a todo custo usar a construção acima, em especial para uma variável de uma letra chamada i. Levou muitos anos para entrar no padrão no C, mas já vão décadas disso. O problema é que depois do loop a variável continua existindo e com esse nome é muito comum acabar sendo usada no meio de algo onde ela não deveria existir.

 

Declare DENTRO do for ou no próprio for. Em C++ se pode declarar também dentro de while() e switch() e foi uma pressão enorme para o comitê aceitar isso. É considerado muito importante reduzir o escopo das variáveis a um máximo.

 

EXEMPLO: reduzindo scope em C++

 

Saida:
 

[0] i = 0
[0] i = 1
[0] i = 2
[0] i = 3
[1] i = 111
[2] i = 2
[3] i = 26
[4] i = 2
[5] i = 111
[6] i = 24
[7] i = 111


O Programa:
 

#include <iostream>
using namespace std;

int main()
{
    int test = 0;
    int i = 111;
    for (int i = 0; i < 4; i += 1)
        cout << "[0] i = " << i << endl;

    cout << "[1] i = " << i << endl;
  
    switch (int i = 2; test)
    {
    case 0: 
        cout << "[2] i = " << i << endl;
        {
            int i = 26;
            cout << "[3] i = " << i << endl;
        }
        cout << "[4] i = " << i << endl;
        break;
    };
    cout << "[5] i = " << i << endl;

    if (int i = 24; test == 0)
        cout << "[6] i = " << i << endl;

    cout << "[7] i = " << i << endl;

}

 

Acompanhe a vida da variável i conforme o programa segue e acho que vai entender. E veja que é possível declarar variáveis locais a um if, um switch, um for ou um simples bloco {} dentro de um case de um switch.

 

E saber que fora dali a variável não existe traz uma grande tranquilidade ;) 

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

@arfneto     obrigado por ajudar , e aquele primeiro código de winAPI  que você postou funcionou , mas esse segundo , não funcionou , tem essa variável que não estou sabendo como declarar ela e de que tipo ela é :

/*case WM_PAINT:   //  este aqui não funcionou , Qual o tipo da variável wInfo
    {
        PAINTSTRUCT ps;
        GetWindowInfo(hWnd, &wInfo);  /  Qual o tipo dessa variável wInfo
        int H = wInfo.rcClient.bottom - wInfo.rcClient.top;
        int W = wInfo.rcClient.right - wInfo.rcClient.left;

        HDC hdc = BeginPaint(hWnd, &ps);
        HDC dc = GetDC(hWnd);
        COLORREF cor = RGB(0, 0, 255); // azul
        for (int x = 0; x < W; x += 1)
        {
            int y = (int)(cos(x * 3.141592 / 180) * H / 2. + H / 2.);
            SetPixel(dc, x, (int)y, cor);
            Sleep(5);
        }   // for()
        EndPaint(hWnd, &ps);
    }
    break;*/

 

e o código funcionou assim  :

// projeto_priprog.cpp : Define o ponto de entrada para o aplicativo.
//

#include "framework.h"
#include "projeto_priprog.h"
#include <cmath>

#define MAX_LOADSTRING 100

// Variáveis Globais:
HDC hc;
HINSTANCE hInst;                                // instância atual
WCHAR szTitle[MAX_LOADSTRING];                  // O texto da barra de título
WCHAR szWindowClass[MAX_LOADSTRING];            // o nome da classe da janela principal
int x;
// Declarações de encaminhamento de funções incluídas nesse módulo de código:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: Coloque o código aqui.

    // Inicializar cadeias de caracteres globais
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_PROJETOPRIPROG, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Realize a inicialização do aplicativo:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_PROJETOPRIPROG));

    MSG msg;

    // Loop de mensagem principal:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



//
//  FUNÇÃO: MyRegisterClass()
//
//  FINALIDADE: Registra a classe de janela.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PROJETOPRIPROG));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_PROJETOPRIPROG);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

//
//   FUNÇÃO: InitInstance(HINSTANCE, int)
//
//   FINALIDADE: Salva o identificador de instância e cria a janela principal
//
//   COMENTÁRIOS:
//
//        Nesta função, o identificador de instâncias é salvo em uma variável global e
//        crie e exiba a janela do programa principal.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // Armazenar o identificador de instância em nossa variável global

   HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

   if ( ! hWnd )
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNÇÃO: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  FINALIDADE: Processa as mensagens para a janela principal.
//
//  WM_COMMAND  - processar o menu do aplicativo
//  WM_PAINT    - Pintar a janela principal
//  WM_DESTROY  - postar uma mensagem de saída e retornar
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    COLORREF cor = RGB(255, 255, 0);
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // Analise as seleções do menu:
            switch (wmId)
            {
            case WM_KEYDOWN:
                if (wParam == VK_ESCAPE)
                {
                    PostQuitMessage(0);
                    DestroyWindow(hWnd);
                    return 0;
                }
                break;
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:   // este aqui funcionou bem
    {
        PAINTSTRUCT ps;

        HDC hdc = BeginPaint(hWnd, &ps);
        HDC dc = GetDC(hWnd);
        COLORREF cor = RGB(255, 0, 0);
        for (int x = 0; x < 1000; x++)
        {
            int y = (int)(cos(x * 3.141592 / 180) * 100. + 250.);
            SetPixel(dc, x, y, cor);
            Sleep(5);
        }   // for()

        EndPaint(hWnd, &ps);
    }
    break;
    /*case WM_PAINT:   //  este aqui não funcionou , Qual o tipo da variável wInfo
    {
        PAINTSTRUCT ps;
        GetWindowInfo(hWnd, &wInfo);  /  Qual o tipo dessa variável wInfo
        int H = wInfo.rcClient.bottom - wInfo.rcClient.top;
        int W = wInfo.rcClient.right - wInfo.rcClient.left;

        HDC hdc = BeginPaint(hWnd, &ps);
        HDC dc = GetDC(hWnd);
        COLORREF cor = RGB(0, 0, 255); // azul
        for (int x = 0; x < W; x += 1)
        {
            int y = (int)(cos(x * 3.141592 / 180) * H / 2. + H / 2.);
            SetPixel(dc, x, (int)y, cor);
            Sleep(5);
        }   // for()
        EndPaint(hWnd, &ps);
    }
    break;*/
    /*case WM_PAINT:  // m este também não funcionou
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            SetPixel(hdc, sin(x * 3.141592 / 180) * 100 + 0,cos(x*3.141592/180)*100+0,cor);
            Sleep(5);
            x++;
            if (x > 360)x = 0;
            // TODO: Adicione qualquer código de desenho que use hdc aqui...
            EndPaint(hWnd, &ps);
        }*/
        //break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// Manipulador de mensagem para a caixa 'sobre'.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

 

e esse outro abaixo , para ver o funcionamento da variável  i  , não está compilando , e mostrou esses erros , que não sei como resolver :

564496683_eeronocodvs.thumb.jpg.2a2529e798720db36d3b302a0f25d905.jpg

Link para o comentário
Compartilhar em outros sites

4 horas atrás, devair1010 disse:

/*case WM_PAINT: // este aqui não funcionou , Qual o tipo da variável wInfo

 

Mas você não está usando Visual Studio? Eu acho que todo IDE moderno faz isso, mas por certo o Visual Studio, que é da Microsoft, a empresa que escreveu o Windows, faz. E aqui é usado aqui para compilar as linguagens com as quais o Windows foi escrito --- basicamente C --- e usando a API do Windows e as funções do header <windows.h>  e o compilador que compilou o Windows e o próprio Visual Studio, o CL.EXE. 

 

Então vou mostrar a seguir o fluxo dessas informações no Visual Studio ---  e mesmo algumas telas --- porque pode ajudar também outros a achar essas coisas.

 

Desculpe não ter postado o programa todo. É que era basicamente o seu programa dentro do esqueleto que o IDE gera.

 

Eis o programa. Não tem nenhuma classe, nada. É só o esqueleto de uma aplicação desktop com o seu código original dentro

 

Spoiler

// WindowsProject2.cpp : Defines the entry point for the application.
//
#include <iostream>
#include <math.h>
#include <numbers>

#include "framework.h"
#include "WindowsProject2.h"

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;                                // current instance
WCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name

// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

LRESULT EditCreate(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam);

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: Place code here.

    // Initialize global strings
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WINDOWSPROJECT2, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT2));

    MSG msg;

    // Main message loop:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT2));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT2);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // Store instance handle in our global variable

   HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE: Processes messages for the main window.
//
//  WM_COMMAND  - process the application menu
//  WM_PAINT    - Paint the main window
//  WM_DESTROY  - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    WINDOWINFO              wInfo;

    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // Parse the menu selections:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            GetWindowInfo(hWnd, &wInfo);
            int H = wInfo.rcClient.bottom - wInfo.rcClient.top;
            int W = wInfo.rcClient.right - wInfo.rcClient.left;

            HDC hdc = BeginPaint(hWnd, &ps);
            HDC dc = GetDC(hWnd);
            COLORREF cor = RGB(0, 0, 255); // azul
            for (int x = 0; x < W; x+=1)
            {
                int y = (int)(cos(x * std::numbers::pi / 180) * H/2. + H/2.);
                SetPixel(dc, x, (int)y, cor);
                Sleep(5);
            }   // for()
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

 

 

 

De volta a GetWindowInfo():

 

Veja:

image.png.a50fa652300fda327012618b0b3c5297.png

Basta você colocar o ponteiro do mouse sobre a função no código e ficar olhando. O IDE mostra a declaração e os parâmetros. Por isso não me preocupei em descrever os 2 parâmetros. É só olhar na tela. Se não aparecem os parâmetros é porque você não incluiu o header. E se apertar o link em azul vai direto para o navegador e veja só a tela

image.png.146f5e00c8d27f2a9b4ecd1b5073ce67.png

Direto ao assunto, na primeira opção a documentação do desenvolvedor sobre a função

Isso também funciona para as classes que você escreve. Até tem uma convenção para mostrar os argumentos, o tipo, a descrição e os valores de retorno das funções que você escreve, usando uns comentários especiais que começam por ///, 3 barras.

 

E a função? pois é, se você apertar o botão direito com o ponteiro sobre o nome da função...

 

image.png.aa943e05ed0f8f5abbe34860a61276a9.pngPois é: Se apertar F12 vai direto para o que? A definição da função. Control-Alt-F12 vai para a declaração. E não precisa nem saber isso porque está sempre na tela. 

E veja Find All References: nada mal. Mostra todos os pontos no projeto inteiro em que a função é usada.

 

E a p0rr@ do argumento? Não está longe. Apertando "Ir para definição" em português, ou F12 em qualquer idioma, vai abrir, como está na tela:
 

image.png.c82f1382ba72f1a93a17bac5726e1628.png

E o editor abre o próprio winuser.h que vem de windows.h e contém a função GetWindowInfo(). Lá estão os parâmetros e é claro que apertar F12 com o cursor em cima dessas coisas em verde vai direto para a definição.
image.png.f6462b37adc677d6c4fb0f63578fe5d5.png
Veja BOOL: 

 

 

E, claro, PWINDOWINFO depois de um mesmo F12:
 

image.png.c7db7ad10d3b0e0bd86befc79a31337f.png

E aqui eu vou recomendar não fazer como está escrito. 

 

NUNCA --- esse é meu palpite --- crie ou use tipos para ponteiros. typedefs na verdade, como esses que estão aí. Essa é uma convenção dos anos 80 da Microsoft e que eu nunca entendi.

 

A estrutura é WINDOWINFO. o P e o LP indicam o que está escrito aí: são ponterios. O LP é de uma época antiga e como vê são a mesma coisa. Em resumo na API tem esses tipos que começam com P e LP e geralmente são ponteiros. A menos que o tipo já comece com P, aí não se sabe se vem PP LPP ou sei lá.

 

Eis o que importa: É muito claro que se WINDOWINFO é uma estrutura então WINDOWINFO* é um ponteiro para ela, bem como WINDOWINFO** é o que é. Não há razão para recriar o óbvio: PPWINDOWINFO seria WINDOWINFO** mas quem se importa? Para que criar isso se fica menos legível? Quando você lê *PWINDOWINFO num programa você  vai ter que pensar se *PWINDOWINFO é ou não WINDOWINFO. Se não usar isso pode simplesmente ler WINDOWINFO, &WINDOWINFO e WINDOWINFO e tudo está claro.

 

Resumindo WINDOWINFO():
 

	WINDOWINFO              wInfo;
	GetWindowInfo(hWnd, &wInfo);

 

Porque não testei o retorno se eu sempre escrevo aqui para testar os valores de retorno? Simples: se essa função falhar para trazer as informações da própria janela do programa então o Windows já era e o seu programa também.
 

4 horas atrás, devair1010 disse:

e esse outro abaixo , para ver o funcionamento da variável  i  , não está compilando , e mostrou esses erros , que não sei como resolver

 

🤔:( Sério?

 

image.png.37ab8c62e448d012b67e514c08320ee4.png

Leu isso antes de postar? que tal requer o sinalizador std=c++17? Esses recursos são uma briga da comunidade desde os anos 90 e só foram finalmente incluídos no padrão na versão 17. A atual é 20. 

 

Esse IDE é um ambiente profissional e caro e usado no mundo inteiro e as empresas tem muitas vezes enormes bases de código e padrões a seguir. Esse é um produto comercial e só recentemente passou a ter uma versão grátis. Isso quer dizer que o padrão da linguagem é convervador para não criar problemas nas empresas que podem depender de algo nas versões anteriores da linguagem e que possa não funcionar em versões recentes da linguagem.

 

Apenas entre nas propriedades do projeto e faça o que está escrito aí na tela, em português:
 

image.png.6ce6f4514b80bb4d81912f80c35dca1c.png

 

 

 

 

 

Até onde eu sei o C++20 está implementado quase todo. Em algum lugar tem um BLOG que explica o estado de cada item. Não me lembro agora.

 

<numbers> e <ranges> por exemplo estão em C++20

  • Curtir 1
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!