Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не рисуються элементы управления, при старте прогрыммы 
V
    Опции темы
cupper
Дата 19.4.2009, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



вот код все програмки, рабочий, написан в DevC++, в MFC кмпилить почти на 100% уверен что небудет.
Код

#include <windows.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
void Sila (double*, double*, double*, double*, double, size_t);
void Nach_uslov (double*, double*, double*, double*, double, size_t, int);
/*  Make the class name into a global variable  */
char szClassName[ ] = "WipAPI";
HWND hEditNum, hEditMas;

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = CreateSolidBrush (RGB(235, 235, 235));

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Жарь молекула",       /* Title Text */
           WS_OVERLAPPED|WS_CAPTION
           |WS_MINIMIZEBOX|WS_SYSMENU, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           600,                 /* The programs width */
           400,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );
    int x=20, y=50;
    CreateWindow ("STATIC",
             "Количество малекул",
             WS_CHILD | WS_VISIBLE,
             x, y, 180, 20,
             hwnd, NULL, hThisInstance, NULL);
    hEditNum = CreateWindowEx(0,
          "EDIT", 
          "10", 
          WS_CHILD | WS_VISIBLE | WS_BORDER | WS_EX_CLIENTEDGE, 
          x, y+30, 100, 20, 
          hwnd, NULL, hThisInstance, NULL);
    CreateWindow ("STATIC",
             "Масса малекул",
             WS_CHILD | WS_VISIBLE,
             x, y+60, 180, 20,
             hwnd, NULL, hThisInstance, NULL);
    hEditNum = CreateWindowEx(0,
          "EDIT", 
          "2", 
          WS_CHILD | WS_VISIBLE | WS_BORDER | WS_EX_CLIENTEDGE, 
          x, y+90, 100, 20, 
          hwnd, NULL, hThisInstance, NULL);
    /* Make the window visible on the screen */
    ShowWindow (hwnd, nFunsterStil);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        static RECT rect; // клиентская облать
        static RECT PS; // облать движения малекул
        //static RECT PSmin; // координаты прямоугольника чтобы малекулы невылетали
        static size_t _x = 200, _y = 10; // координаты верхнего левого угла, области движения малекул
        GetClientRect(hwnd, &rect); 
        SetRect (&PS, _x, _y, rect.right - 10, rect.bottom - 10);
        static HBRUSH hbrBlack = (HBRUSH) GetStockObject (BLACK_BRUSH);
        static HBRUSH hbrPS = (HBRUSH) GetStockObject (WHITE_BRUSH);
        
        const static size_t N = 20; // число материальных точек
        static double Fx[N], Fy[N], x[N], y[N], vx[N], vy[N], xx[N], yy[N];
        int Gd, Gm;
        static double m;
        double ax, ay;
        static double dt = 0.01;
        static int Radius = 10;
        static int __x1 = Radius + 1, __y1 = Radius + 1;
        static int __x2 = 372, __y2 = 335; 
        
        static HBRUSH hBrush, oldbrush;
        static HPEN hPen, oldpen;
        
         int lenNum;
         int lenMas;

        
    switch (message)                  /* handle the messages */
    {
        case WM_CREATE:
             hBrush = CreateSolidBrush(RGB(255, 0, 0));
             hPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
             Nach_uslov(x, y, vx, vy, m, N, Radius);
             //-------------------------------------------------------
             /*lenNum = GetWindowTextLength(hEditNum);
             lenMas = GetWindowTextLength(hEditMas);
             char strNum[lenNum];
             char strMas[lenMas];
             if (lenMas == 1) MessageBox(hwnd, "1","", MB_YESNO | MB_ICONQUESTION);
             if (lenMas == 0) MessageBox(hwnd, "0","", MB_YESNO | MB_ICONQUESTION);
             GetWindowText(hEditNum,strNum,lenNum);
             GetWindowText(hEditMas,strMas,lenMas);
             MessageBox(hwnd, strMas,"", MB_YESNO | MB_ICONQUESTION);
             //int k = atoi (strNum);
             if (lenMas == 0) m = 2;
             else m = atof (strMas);*/
//-------------------------------------------------------
             break;
        case WM_PAINT:
             hdc = BeginPaint(hwnd, &ps);
             oldbrush= (HBRUSH)SelectObject(hdc, hBrush);
             oldpen= (HPEN)SelectObject(hdc, hPen);
             Sila (Fx, Fy, x, y, m, N);
             for (size_t i=0; i<N; ++i){
                 ax=Fx[i]/m;
                 ay=Fy[i]/m;
                 vx[i]=vx[i]+ax*dt;
                 vy[i]=vy[i]+ay*dt;
                 x[i]=x[i]+vx[i]*dt;
                 y[i]=y[i]+vy[i]*dt;
                 if (x[i]< __x1 || x[i]> __x2){
                    vx[i]=-vx[i];
                    if (x[i]< __x1) x[i]=__x1;
                    else x[i]=__x2;
                 }
                 if (y[i]< __y1  || y[i]> __y2){
                    vy[i]=-vy[i];
                    if (y[i]< __y1) y[i]=__y1;
                    else y[i]=__y2;
                 }
             }
             FillRect (hdc, &PS, hbrPS);
             FrameRect (hdc, &PS, hbrBlack);
             for (size_t i=0; i<N; ++i){
                 Ellipse(hdc, _x + (int)x[i]-Radius, _y + (int)y[i]-Radius,
                              _x + (int)x[i]+Radius, _y + (int)y[i]+Radius);
             }
             SelectObject(hdc, oldbrush);
             SelectObject(hdc, oldpen);
             Sleep (20);
             EndPaint(hwnd, &ps);
             InvalidateRect(hwnd, &PS, true);
             break;
        case WM_DESTROY:
             DeleteObject(hBrush);
             DeleteObject(hPen);
             PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
             break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

void Sila (double* Fx, double* Fy, double* x, double* y, double m, size_t N){
     for (size_t i=0; i<N; ++i){
         Fx[i]=0;
         Fy[i]=0;
     }
     double l, F;
     for (size_t i=0; i<N; ++i){
         for (size_t j=0; j<N; ++j){
             if (j==i) continue;
             l = sqrt(pow((x[i] - x[j]), 2) + pow((y[i]- y[j]), 2));
             if (l<2) l=2;
             F = -50000*m/*[i]*/*m/*[j]*//pow(l, 2) + 500000*m/*[i]*/*m/*[j]*//pow((l*l), 2);
             Fx[i] = Fx[i] + F*(x[i] - x[j])/l;
             Fy[i] = Fy[i] + F*(y[i] - y[j])/l + m/*[i]*/*10;
         }
     }
     
}
     
void Nach_uslov (double* x, double* y, double* vx, double* vy, double m, size_t N, int radius){
     srand (time(NULL));
     m=2;
     for (size_t i=0; i<N; ++i){
         x[i]=rand()%350 + radius;
         y[i]=rand()%300 + radius;
         vx[i]=rand()%30 - 65;
         vy[i]=rand()%30 - 65;
     }
}



что значит происходит:
запускаю программу, появляеться квадрат и там происходит некоторая байда (то что запрограммировал то и происходит). Но нерисуються элементы
Код

int x=20, y=50;
    CreateWindow ("STATIC",
             "Количество малекул",
             WS_CHILD | WS_VISIBLE,
             x, y, 180, 20,
             hwnd, NULL, hThisInstance, NULL);
    hEditNum = CreateWindowEx(0,
          "EDIT", 
          "10", 
          WS_CHILD | WS_VISIBLE | WS_BORDER | WS_EX_CLIENTEDGE, 
          x, y+30, 100, 20, 
          hwnd, NULL, hThisInstance, NULL);
    CreateWindow ("STATIC",
             "Масса малекул",
             WS_CHILD | WS_VISIBLE,
             x, y+60, 180, 20,
             hwnd, NULL, hThisInstance, NULL);
    hEditNum = CreateWindowEx(0,
          "EDIT", 
          "2", 
          WS_CHILD | WS_VISIBLE | WS_BORDER | WS_EX_CLIENTEDGE, 
          x, y+90, 100, 20, 
          hwnd, NULL, hThisInstance, NULL);


они прорисовываются только после того как непосредственно повлиять на окно программы, или щелкнуть по нему или переместить.
Если закоментить весь
Код

case WM_PAINT:
...
break;

и запустить программу то выше перечисленные элементы нормально прорисовываються при старте.
Преждем чем отвечать попробуйте скомпилить, так наглядней будет понятно о чем я говорю.
PM MAIL   Вверх
yeputons
Дата 19.4.2009, 23:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 1.4.2009
Где: Санкт-Петербург

Репутация: 1
Всего: 5



насколько понимаю ситуацию я, проблема заключается в строчке кода #187:
Код

             InvalidateRect(hwnd, &PS, true);

Если ты закомментируешь эту строчку, то всё прорисуется нормально.

Решение
Требуется убрать эту строчку из обработки сообщения WM_PAINT. Для бесконечной перерисовки могу посоветовать использовать таймеры. Это делается так: процедуру WinMain изменяем так:
Код

HANDLE hTimer;
...
if (!SetTimer(hwnd, 1, 100, NULL)) return 0; //Создаём таймер для окна hwnd с номером 1 и интервалом в 100 мс.
while (!GetMessage(...)) {
  ...
}
KillTimer(hwnd, 1); //Удаляем таймер
...

А в WndProc добавляем в case:
Код

case WM_TIMER:
  if (wParam == 1) //Если сработал наш таймер #1, то
    SendMessage(hwnd, WM_PAINT, 0, 0); // Скажем нашему окну (обрати внимание, что hwnd тут - не параметр) перерисоваться
  break;


Объяснение
 Я понял, что эта строчка служит для бесконечной перерисовки окна (функция InvalidateRect говорит системе, что такой-то регион у такого-то окна надо перерисовать). Она вызывается, когда перерисовка еще не закончена (не прорисовались дочерние контролы) и система после обработки сообщения WM_PAINT видит, что хорошо бы перерисовать дочерние окна, но вот беда - надо обновить всё окно... поехали посылать WM_PAINT. И т.о. система просто не доходит то перерисовки надписей и Edit'ов.

PM MAIL ICQ Skype   Вверх
cupper
Дата 19.4.2009, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



я чета примерное подразумевал, спасибо за подробное объяснение, щас попробую ваш вариант.

Добавил ваш код, но перерисовки непроисходит :(
я с таймерами неработал, поэтому могу бональной опечатки незаметить у вас, так что покачто безрезультатно

непонятно ваша фраза
(обрати внимание, что hwnd тут - не параметр)
а чтоже это ?

Это сообщение отредактировал(а) cupper - 19.4.2009, 23:38
PM MAIL   Вверх
GremlinProg
Дата 19.4.2009, 23:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



да, однозначно, проблема конечно в InvalidateRect на WM_PAINT

BeginPaint помечает область окна закрашенной, т.е. не требующей дальнейшей прорисовки, а InvalidateRect - наоборот - незакрашенной
в итоге, на входе WM_PAINT есть незакрашенная область, и на выходе WM_PAINT - то же самое, что приводит к бесконечным посылкам WM_PAINT одному окну

но в таймере WM_PAINT посылать напрямую окну тоже не стоит, достаточно вызвать тот же InvalidateRect

альтернатива таймеру - перерисовка в фоне (OnIdle и т.п.)


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
cupper
Дата 19.4.2009, 23:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



но в таймере WM_PAINT посылать напрямую окну тоже не стоит, достаточно вызвать тот же InvalidateRect
вот красавчик smile спс большое !!! жаль нет 100 сообщение + немогу поставить :(
PM MAIL   Вверх
yeputons
Дата 20.4.2009, 00:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 1.4.2009
Где: Санкт-Петербург

Репутация: 1
Всего: 5



достаточно вызвать тот же InvalidateRect
согласен. С окошками WinAPI не очень активно работаю, юзаю CodeGear C++ Builder smile)

(обрати внимание, что hwnd тут - не параметр)
У WndProc есть параметр hWnd - хэндл окна, которому было послано сообщение. А перерисовать надо окно hwnd - которое мы создали в WinMain. Конечно, в этой программе это одно и тоже, но иногда бывает иначе.

PM MAIL ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.3487 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.