[resolvido]((C++ par win 32)) Por que deu erro?

Estou aprendendo C++ para win32, mais ta muito mais ph0d@ que Java. Eu não quero depender de nenhum IDE como VS então estou tentando aprender sem “desenhar interfaces”, mais programa-las no braço.

resorce.rc:

#include "resource.h" // REcursos

DLG_MAIN DIALOGEX 6, 5, 194, 106

CAPTION "First C++ win project"

FONT 8, "Tahoma"

STYLE 0x10CE0804

BEGIN
  CONTROL "&Test", IDC_BTN_TEST, "Button", 0x10010000, 138,  5, 46, 15
  CONTROL "&Quit", IDC_BTN_QUIT, "Button", 0x10010000, 138, 29, 46, 15
  CONTROL "EXIBE", IDC_BTN_SHOW, "Button", 0x10010000, 138, 50, 46, 15
END

resorce.h

#include <windows.h> // resorces(resorce.h)

// ID of Main Dialog
#define DLG_MAIN 101

// ID of Button Controls
#define IDC_BTN_TEST 1001
#define IDC_BTN_QUIT 1002
#define IDC_BTN_SHOW 1003

Projeto principal (main.cpp)

[code]#define WIN32_LEAN_AND_MEAN //Main.cpp(arquivo principal)

#include <windows.h>

#include “resource.h”

HINSTANCE hInst;

BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
/*
* TODO: Add code to initialize the dialog.
*/
return TRUE;

    case WM_CLOSE:
        EndDialog(hwndDlg, 0);
        return TRUE;

    case WM_COMMAND:
        switch(LOWORD(wParam))
        {
            /*
             * TODO: Add more control ID's, when needed.
             */
            case IDC_BTN_SHOW: // Erro, invalid conversion from 'int' do constant CHAR*;
                MessageBox(hwndDlg, "Consegui adicionar eventos a botões", MB_ICONINFORMATION);
                return TRUE;// Erro, invalid conversion from 'int' do constant CHAR*;


            case IDC_BTN_QUIT:
                EndDialog(hwndDlg, 0);
                return TRUE;

            case IDC_BTN_TEST:
                MessageBox(hwndDlg, "You clicked \"Test\" button!", "Information", MB_ICONINFORMATION);
                return TRUE;

        }
}

return FALSE;

}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
hInst = hInstance;

// The user interface is a modal dialog box
return DialogBox(hInstance, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DialogProc);

}

[/code]

Adquira esse livro. Eu tenho, é muito bom. Enorme e pesado também.

Agora, fazer aplicações Windows diretamente no braço é geralmente uma perda de tempo. Além de extremamente trabalhoso e pouco produtivo, principalmente sem usar um IDE.

Outra coisa. Seu código está escrito em C, não em C++. Várias práticas utilizadas por você não são recomendadas no C++, como criar constantes através de defines. É uma boa ler esse livro aqui também: http://www.informit.com/store/product.aspx?isbn=032151582X

Para fazer isso no braço (eu também já fiz isso, quando programar em Windows em C era sexy), existe um livro muito famoso, pelo sr. Charles Petzold.
Talvez você consiga achá-lo em alguma biblioteca:

Programming Windows, 4th edition

http://www.charlespetzold.com/books.html

No seu caso (que é programação 32 bits, não 16 bits), é melhor usar a 4a. edição, não a 3a. , que foi a que usei nos meus tempos de novato no Windows.

ahhaha, é o livro grande e pesado que recomendei (que também comprei na época que programar no braço era sexy).

Hoje o livro está na quinta edição.

Eu não acho muito difícil, já diz muitas aplicações “no braço” em outras linguagens porque não encontrei nada que presta para desenhar interfaces, ou é pago ou gera muito lixo.

Pai, perdoai-lhe, ele não sabe o que diz.

Vamos a um exemplo. Se vc quiser colocar um ScrollBar na tela, vc a inicializa assim:

//---------------------------------------------------------------------------
LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg,
                         WPARAM wParam, LPARAM lParam)
{
    HWND hWndScroller;
    SCROLLINFO si;

    hWndScroller = GetDlgItem(hWndDlg, IDC_SCROLLER);

    switch(Msg)
    {
    case WM_INITDIALOG:
        ZeroMemory(&si, sizeof(si));
        si.cbSize = sizeof(si);
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS;
        si.nMin   = 0;
        si.nMax   = 240;
        si.nPage  = 10;
        si.nPos   = 54;
        SetScrollInfo(hWndScroller, SB_CTL, &si, TRUE);

        return TRUE;

    case WM_COMMAND:
        switch(wParam)
        {
            case IDC_CLOSE_BTN:
            EndDialog(hWndDlg, 0);
            return TRUE;
        }
        break;

        case WM_CLOSE:
                PostQuitMessage(WM_QUIT);
                break;
        }

        return FALSE;
}

Mas isso não é suficiente. Isso só desenha o scrollbar, mas ela não se move! Para que ela se mova, vc precisa processar os eventos de scroll, mais ou menos assim:

#ifdef __BORLANDC__
  #pragma argsused
#endif

#include "resource.h"
//---------------------------------------------------------------------------
HWND hWnd;
HINSTANCE hInst;
LRESULT CALLBACK DlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
//---------------------------------------------------------------------------
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    hInst = hInstance;

    DialogBox(hInst, MAKEINTRESOURCE(IDD_CONTROLS_DLG),
              hWnd, reinterpret_cast&lt;DLGPROC&gt;(DlgProc));

  return 0;
}
//---------------------------------------------------------------------------
LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg,
                       WPARAM wParam, LPARAM lParam)
{
    HWND hWndScroller;
    SCROLLINFO si;
    int CurPos;
    char strPosition[20];

    hWndScroller = GetDlgItem(hWndDlg, IDC_SCROLLER);

    switch(Msg)
    {
    case WM_INITDIALOG:
        CurPos = 0;

        ZeroMemory(&si, sizeof(si));
        si.cbSize = sizeof(si);
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS;
        si.nMin   = 0;
        si.nMax   = 240;
        si.nPage  = 10;
        si.nPos   = 54;
        SetScrollInfo(hWndScroller, SB_CTL, &si, TRUE);

        sprintf(strPosition, &quot;%d&quot;, si.nPos);
        SetDlgItemText(hWndDlg, IDC_LABEL, strPosition);

        return TRUE;

    case WM_VSCROLL:
                CurPos = GetScrollPos(hWndScroller, SB_CTL);

                switch (LOWORD(wParam))
                {
                case SB_TOP:
                        CurPos = 0;
                        break;

                case SB_LINEUP:
                        if (CurPos &gt; 0)
                                CurPos--;
                        break;

                case SB_THUMBPOSITION:
                        CurPos = HIWORD(wParam);
                        break;

                case SB_THUMBTRACK:
                        CurPos = HIWORD(wParam);
                        break;

                case SB_LINEDOWN:
                        if (CurPos &lt; 240)
                                CurPos++;
                        break;

                case SB_BOTTOM:
                        CurPos = 240;
                        break;

                case SB_ENDSCROLL:
                        break;
                }

        SetScrollPos(hWndScroller, SB_CTL, CurPos, TRUE);

        sprintf(strPosition, &quot;%d&quot;, CurPos);
        SetDlgItemText(hWndDlg, IDC_LABEL, strPosition);

        break;

    case WM_COMMAND:
        switch(wParam)
        {
            case IDC_CLOSE_BTN:
            EndDialog(hWndDlg, 0);
            return TRUE;
        }
        break;

        case WM_CLOSE:
                PostQuitMessage(WM_QUIT);
                break;
        }

        return FALSE;
}

Detalhe que nesse código tem coisas hardcoded, para um tamanho de janela específico. Se quiser fazer algo genérico, você teria que adicionar uns 20 ou 30% a mais de código.

No java vc geralmente resolve isso com apenas 1 linha.

Por isso não é bom comparar Win32 padrão com "APIs gráficas de outras linguagens".

Pai, perdoai-lhe, ele não sabe o que diz.

Vamos a um exemplo. Se vc quiser colocar um ScrollBar na tela, vc a inicializa assim:

//---------------------------------------------------------------------------
LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg,
                         WPARAM wParam, LPARAM lParam)
{
    HWND hWndScroller;
    SCROLLINFO si;

    hWndScroller = GetDlgItem(hWndDlg, IDC_SCROLLER);

    switch(Msg)
    {
    case WM_INITDIALOG:
        ZeroMemory(&si, sizeof(si));
        si.cbSize = sizeof(si);
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS;
        si.nMin   = 0;
        si.nMax   = 240;
        si.nPage  = 10;
        si.nPos   = 54;
        SetScrollInfo(hWndScroller, SB_CTL, &si, TRUE);

        return TRUE;

    case WM_COMMAND:
        switch(wParam)
        {
            case IDC_CLOSE_BTN:
            EndDialog(hWndDlg, 0);
            return TRUE;
        }
        break;

        case WM_CLOSE:
                PostQuitMessage(WM_QUIT);
                break;
        }

        return FALSE;
}

Mas isso não é suficiente. Isso só desenha o scrollbar, mas ela não se move! Para que ela se mova, vc precisa processar os eventos de scroll, mais ou menos assim:

#ifdef __BORLANDC__
  #pragma argsused
#endif

#include "resource.h"
//---------------------------------------------------------------------------
HWND hWnd;
HINSTANCE hInst;
LRESULT CALLBACK DlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
//---------------------------------------------------------------------------
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    hInst = hInstance;

    DialogBox(hInst, MAKEINTRESOURCE(IDD_CONTROLS_DLG),
              hWnd, reinterpret_cast&lt;DLGPROC&gt;(DlgProc));

  return 0;
}
//---------------------------------------------------------------------------
LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg,
                       WPARAM wParam, LPARAM lParam)
{
    HWND hWndScroller;
    SCROLLINFO si;
    int CurPos;
    char strPosition[20];

    hWndScroller = GetDlgItem(hWndDlg, IDC_SCROLLER);

    switch(Msg)
    {
    case WM_INITDIALOG:
        CurPos = 0;

        ZeroMemory(&si, sizeof(si));
        si.cbSize = sizeof(si);
        si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS;
        si.nMin   = 0;
        si.nMax   = 240;
        si.nPage  = 10;
        si.nPos   = 54;
        SetScrollInfo(hWndScroller, SB_CTL, &si, TRUE);

        sprintf(strPosition, &quot;%d&quot;, si.nPos);
        SetDlgItemText(hWndDlg, IDC_LABEL, strPosition);

        return TRUE;

    case WM_VSCROLL:
                CurPos = GetScrollPos(hWndScroller, SB_CTL);

                switch (LOWORD(wParam))
                {
                case SB_TOP:
                        CurPos = 0;
                        break;

                case SB_LINEUP:
                        if (CurPos &gt; 0)
                                CurPos--;
                        break;

                case SB_THUMBPOSITION:
                        CurPos = HIWORD(wParam);
                        break;

                case SB_THUMBTRACK:
                        CurPos = HIWORD(wParam);
                        break;

                case SB_LINEDOWN:
                        if (CurPos &lt; 240)
                                CurPos++;
                        break;

                case SB_BOTTOM:
                        CurPos = 240;
                        break;

                case SB_ENDSCROLL:
                        break;
                }

        SetScrollPos(hWndScroller, SB_CTL, CurPos, TRUE);

        sprintf(strPosition, &quot;%d&quot;, CurPos);
        SetDlgItemText(hWndDlg, IDC_LABEL, strPosition);

        break;

    case WM_COMMAND:
        switch(wParam)
        {
            case IDC_CLOSE_BTN:
            EndDialog(hWndDlg, 0);
            return TRUE;
        }
        break;

        case WM_CLOSE:
                PostQuitMessage(WM_QUIT);
                break;
        }

        return FALSE;
}

Detalhe que nesse código tem coisas hardcoded, para um tamanho de janela específico. Se quiser fazer algo genérico, você teria que adicionar uns 20 ou 30% a mais de código.

No java vc geralmente resolve isso com apenas 1 linha.

Por isso não é bom comparar Win32 padrão com "APIs gráficas de outras linguagens".[/quote]

Vixe, você estava certo. Uma coisa é simples botões, mais o problema é que nunca encontrei nada de bom para desenhar automaticamente, já tentei usar o netBeans(não desenha interface), QT creator gera muito lixo e não consigo executar meus programas fora dele, code::blocks: nao consigo desenhar interface, sempre da erro, C++ bluider: este não consigo nem executar(windows 64 bits), em fim se souber uma ferramenta para faciiltar isto e que funcione, eu agradeço.

O qt é excelente. Baixe o qt e tente fazer as interfaces no braço, não no QtDevelop.
Ao encontrar dificuldades, procure superá-las, não trocar de API.

E dá para usar fora dele também.

[quote=ViniGodoy]O qt é excelente. Baixe o qt e tente fazer as interfaces no braço, não no QtDevelop.
Ao encontrar dificuldades, procure superá-las, não trocar de API.

E dá para usar fora dele também.[/quote]

Sim, mais ao tentar executar fora dele, ele pede uma dll que mal sei onde esta.

Sem contar que, aprendendo o Qt direitinho, dá para usar seu conhecimento para escrever aplicações para Nokia e outros celulares que usam o mesmo sistema operacional Symbian, como alguns LGs e Samsungs. Por exemplo, SonyEricsson: http://www.sonyericsson.com/br/preview/tag/symbian

[quote=DarthVictor][quote=ViniGodoy]O qt é excelente. Baixe o qt e tente fazer as interfaces no braço, não no QtDevelop.
Ao encontrar dificuldades, procure superá-las, não trocar de API.

E dá para usar fora dele também.[/quote]

Sim, mais ao tentar executar fora dele, ele pede uma dll que mal sei onde esta.[/quote]

Você tem é que aprender como usar o Windows.

Vá até o site Sysinternals ( http://technet.microsoft.com/pt-br/sysinternals/default.aspx ), baixe o Process Explorer, e rode seu programa Qt, e veja onde estão as DLLs que ele carrega com o utilitário Process Explorer. Não tenho um programa Qt aqui para rodar e demonstrar - vou dar um exemplo com o WinMerge. Rode o Process Explorer, tecle Ctrl+D para mostrar as DLLs, selecione o processo que você quer examinar, e então selecione a DLL que você quer encontrar. Clique com o botão direito, escolha Properties, e aí vai descobrir onde está a DLL que ele precisa.


[quote=bezier curve][quote=DarthVictor][quote=ViniGodoy]O qt é excelente. Baixe o qt e tente fazer as interfaces no braço, não no QtDevelop.
Ao encontrar dificuldades, procure superá-las, não trocar de API.

E dá para usar fora dele também.[/quote]

Sim, mais ao tentar executar fora dele, ele pede uma dll que mal sei onde esta.[/quote]

Você tem é que aprender como usar o Windows.

Vá até o site Sysinternals ( http://technet.microsoft.com/pt-br/sysinternals/default.aspx ), baixe o Process Explorer, e rode seu programa Qt, e veja onde estão as DLLs que ele carrega com o utilitário Process Explorer. Não tenho um programa Qt aqui para rodar e demonstrar - vou dar um exemplo com o WinMerge. Rode o Process Explorer, tecle Ctrl+D para mostrar as DLLs, selecione o processo que você quer examinar, e então selecione a DLL que você quer encontrar. Clique com o botão direito, escolha Properties, e aí vai descobrir onde está a DLL que ele precisa.

[/quote]

Obrigado. Não sei como fui idiota de não pensar em baixar as dll`s.

Se você não usa o Process Explorer, não sabe o que está perdendo. Não consigo fazer nada sem ele - ele me salvou muitas vezes a pele.