Avatar billede mr_wiseguy Nybegynder
07. september 2003 - 11:24 Der er 21 kommentarer og
1 løsning

Screensaver i Borland C++

Hejsa. Jeg ønsker at lave en screensaver i Borland C++, som skal kunne lukke nogle Win98 maskiner ned. Jeg er MEGET grøn hvad angår C++. Jeg har første del af koden, som når jeg kompilerer den, så ændrer jeg .exe filen til en scr fil. Derefter ligger jeg den ind i system mappen i windows, og vælger den som screensaver. Mit problem er nu, at så snart screensaveren bliver aktiveret, så lukker den ikke windows. Istedet starter den bare en masse commandopromt vinduer. Min kode er som følgende:

#include <windows.h>
#include <scrnsave.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main()
{
for ( int i = 0 ; i < 60 * 3 ; i++ )
    Sleep(60000) ;
    ExitWindowsEx( EWX_POWEROFF + EWX_FORCE, 0 );

    return 0 ;
}

Please hjælp. Det er ret vigtigt, at det kommer til at spille.
P.S Spørgsmålet er også oprettet andetsteds. Beklager.
Avatar billede driis Nybegynder
07. september 2003 - 15:04 #1
Det er delvist rigtigt, at en screensaver 'bare' er en almindelig .exe fil, der er omdøbt til .scr. Men det skal være et Windows program, og ikke et konsol program som det ovenstående.

Du kan lave en screensaver, der kan lukke computeren ned med følgende kode. Du skal linke til scrnsave.lib og comctl32.lib. Jeg har kun testet med MS VC++ 7, men det bør virke på alle nyere compilere, evt. efter lidt tilretninger:


// Screensaver, der lukker maskinen ned efter x antal minutter.
//

#include "windows.h"
#include "scrnsave.h"

#define TTL_BEFORE_SHUTDOWN 1 // Tid i minutter, før systemet lukkes, mens screensaveren kører.
#define SZ_TXT  "Tid til nedlukning: "
#define SZ_HOURS " timer, "
#define SZ_MINS  " minutter, og "
#define SZ_SECS  " sekunder."

// funktion, der kan lukke windows, dur også i NT / XP
bool ShutDownSystem(long flag)
{
    OSVERSIONINFO        vi ;
    LUID                luid ;
    HANDLE                hProcess, hToken ;
    long                ret = -1 ;
    DWORD                s ;
    TOKEN_PRIVILEGES    tp, tpOld ;

    vi.dwOSVersionInfoSize = sizeof(vi) ;
    GetVersionEx(&vi) ;
    if ( vi.dwPlatformId == VER_PLATFORM_WIN32_NT )
    {
        // Der køres NT, og vi skal have lavet rettigheder til at lukke systemet ned
        if ( LookupPrivilegeValue(0,SE_SHUTDOWN_NAME,&luid) )
        {
            hProcess = GetCurrentProcess()  ;
            if ( hProcess )
            {
                if ( OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) )
                {
                    tp.PrivilegeCount = 1 ;
                    tp.Privileges->Attributes = SE_PRIVILEGE_ENABLED ;
                    tp.Privileges->Luid.HighPart = luid.HighPart ;
                    tp.Privileges->Luid.LowPart = luid.LowPart  ;
                    ret = AdjustTokenPrivileges(hToken, FALSE,&tp,sizeof(tp),&tpOld,&s) ;
                }
                CloseHandle(hToken) ;
            }
        }
    }
   
    if ( ExitWindowsEx(flag,0) )
        return true ;
    else
        return false ;   
}

LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static long seconds = 0 ;
    char txt[80] = {0} ;
    static HDC hDC = GetDC(hWnd) ;
    static UINT_PTR uTimer = 0;
    size_t old_len = 0 ;

    RECT txtrect ;

    int xpos,
        ypos,
        hrs,
        mins,
        secs ;
   
    switch(message)
    {
    case WM_CREATE:            // her oprettes vinduet.

        uTimer = SetTimer(hWnd, 1, 1000, NULL);
        break;

    case WM_DESTROY:        // Afslut timer
        if(uTimer)
            KillTimer(hWnd, uTimer);

        PostQuitMessage(0);
        break;

    case WM_TIMER:
       
        seconds++ ;
        if ( seconds / 60 >= TTL_BEFORE_SHUTDOWN )
        {
            ShutDownSystem(EWX_POWEROFF) ;        // her lukkes systemet           
        }

        secs = TTL_BEFORE_SHUTDOWN * 60 - seconds ;
        hrs = secs / 3600 ;                    // 3600 sekunder = én time.
        mins = ( secs - ( hrs * 3600 ) ) / 60 ;
        secs = ( secs - (( secs / 60 ) * 60 ) ) ;

        strcpy(txt,SZ_TXT) ;
        itoa(hrs,txt+strlen(txt),10) ;
        strcpy(txt+strlen(txt),SZ_HOURS) ;
        itoa(mins,txt+strlen(txt),10) ;
        strcpy(txt+strlen(txt),SZ_MINS) ;
        itoa(secs,txt+strlen(txt),10) ;
        strcpy(txt+strlen(txt),SZ_SECS) ;
       
        xpos = GetSystemMetrics(SM_CXSCREEN) / 2;
        ypos = GetSystemMetrics(SM_CYSCREEN) / 2;
        txtrect.bottom = ypos + 50 ;
        txtrect.top = ypos - 50 ;
        txtrect.right = xpos + 200 ;
        txtrect.left =  xpos - 200 ;

        if ( strlen(txt) < old_len  )
            FillRect(hDC,&txtrect,(HBRUSH)(COLOR_BACKGROUND+1)) ;
       
        old_len = strlen(txt) ;
        DrawText(hDC,txt,-1,&txtrect,DT_CENTER | DT_VCENTER) ;

        break ;



    default:
        return DefScreenSaverProc(hWnd, message, wParam, lParam);
    }
   
    return 0;
}

BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    return FALSE;        // returner false, vi vil ikke vise en konfigurer dialog.
}

BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
{
    return TRUE;
}
Avatar billede driis Nybegynder
07. september 2003 - 15:06 #2
Det er ikke kønt, men det viser hvordan det kan gøres. Så må du selv lege med det visuelle.
Avatar billede mr_wiseguy Nybegynder
07. september 2003 - 15:33 #3
Jeg får 2 errors, når jeg kompilerer det.
Den ene er "static UINT_PTR uTimer = 0;" //Her får jeg Declaration syntax error
Den anden er "uTimer = SetTimer(hWnd, 1, 1000, NULL);" // Her diger den Undefined symbol 'uTimer'

Ved du evt. hvad disse er?

Du siger i indledningen at jeg skal linke til scrnsave.lib og comctl32.lib. Hvordan gør jeg det?
Avatar billede mr_wiseguy Nybegynder
07. september 2003 - 15:41 #4
Kan man hente en demo af MS VC++ så man kunne prøve at kompiele det?
Avatar billede driis Nybegynder
07. september 2003 - 16:18 #5
Prøv at erstatte
static UINT_PTR uTimer = 0 ;
med
static UINT uTimer = 0 ;
eller
static long uTimer = 0 ;
Avatar billede arne_v Ekspert
07. september 2003 - 16:24 #6
Ikke fordi det er specielt relevant.

Men kan UINT_PTR og UINT være det samme ?

(navnene lyder meget som en pointer til unsigned int og en unsigned int)
Avatar billede mr_wiseguy Nybegynder
07. september 2003 - 16:33 #7
Nu får jeg en fejl som hedder : "Undefined symbol_main referenced from c:\programmer\borland\cbuilder\lib\cox32.obj

Tror nok der står COX32.OBJ. Det er lidt svært
Avatar billede driis Nybegynder
07. september 2003 - 16:46 #8
arne_v >> Nej, selvfølgelig er det ikke det samme. Men jeg har set begge typer blive brugt til at modtage returværdien fra uTimer. Værdien bliver ikke brugt igen i dette tilfælde, så det burde ikke betyde noget.

mr_wiseguy>> Linker du til scrnsave.lib og comctl32.lib ?
Avatar billede mr_wiseguy Nybegynder
07. september 2003 - 16:48 #9
Kan ikke finde scrnsave.lib nogen steder. Gætter på at den skulle ligge i LIB Biblioteket.
Avatar billede mr_wiseguy Nybegynder
07. september 2003 - 16:49 #10
Comctl32.lib kan jeg heller ikke finde
Avatar billede mr_wiseguy Nybegynder
07. september 2003 - 17:02 #12
Hvor kan jeg finde disse to filer?
Avatar billede driis Nybegynder
07. september 2003 - 17:34 #13
De er en del af blandt andet MS VC++ distributionen, men også blandt andet i Open Watcom, som du kan finde her:

http://openwatcom.mirrors.pair.com/watcom/open-watcom-win32-1.0.exe

Når du installerer Open Watcom, placeres de 2 filer i lib386\nt. Du kan med fordel prøve at compile screensaveren i Open Watcoms compiler, det er muligt at den uden videre kan compile versionen med notationen:
static UINT_PTR uTimer = 0 ;
, som er den korrekte måde at gøre det på, som arne_v ganske rigtigt pointerer. Jeg ved ikke hvorfor UINT_PTR ikke er erklæret i Borlands windows.h header.
Avatar billede mr_wiseguy Nybegynder
07. september 2003 - 17:51 #14
Når du siger "linker" scrnsave.lib og comctl32.lib, mener du så inkludere som header fil. altså :

#include "scrnsave.lib"
#include "comctl32.lib"
Avatar billede mr_wiseguy Nybegynder
07. september 2003 - 17:53 #15
I Open Watcom. Hvilken en er Kompileren??
Avatar billede driis Nybegynder
07. september 2003 - 17:54 #16
Nej, det er en linker indstilling. Jeg ved ikke helt hvordan du indstiller det i Borland. Prøv at søge efter det i hjælpen.
Avatar billede mr_wiseguy Nybegynder
07. september 2003 - 18:10 #17
Er det noget i stil med disse?

USELIB("\Programmer\Borland\CBuilder\LIB\comctl32.lib");
USELIB("\Programmer\Borland
Avatar billede mr_wiseguy Nybegynder
07. september 2003 - 18:11 #18
Uddskyld:

USELIB("\Programmer\Borland\CBuilder\LIB\comctl32.lib");
USELIB("\Programmer\Borland\CBuilder\LIB\scrnsave.lib");
Avatar billede mr_wiseguy Nybegynder
07. september 2003 - 18:13 #19
Hvis jeg kører programmet og inkludere som overstående, så får jeg 2 fejl der hedder : "} expected"
Når jeg klikker på disse, så viser den ene at det er USELIB("\Programmer\Borland\CBuilder\LIB\comctl32.lib"); der er noget galt med og den anden siger t det er USELIB("\Programmer\Borland\CBuilder\LIB\scrnsave.lib"); der ikke kører
Avatar billede mr_wiseguy Nybegynder
07. september 2003 - 18:20 #20
Er det ikke muligt at finde et VC++ kompiler program?
Avatar billede mr_wiseguy Nybegynder
07. september 2003 - 18:34 #21
Nu ser min kode ud som

#include "windows.h"
#include "scrnsave.h"

USELIB("\Programmer\Borland\CBuilder\LIB\comctl32.lib");
USELIB("\Programmer\Borland\CBuilder\LIB\scrnsave.lib");
//---------------------------------------------------------------------------

#define TTL_BEFORE_SHUTDOWN 1 // Tid i minutter, før systemet lukkes, mens screensaveren kører.
#define SZ_TXT  "Tid til nedlukning: "
#define SZ_HOURS " timer, "
#define SZ_MINS  " minutter, og "
#define SZ_SECS  " sekunder."

// funktion, der kan lukke windows, dur også i NT / XP
bool ShutDownSystem(long flag)
{
    OSVERSIONINFO        vi ;
    LUID                luid ;
    HANDLE                hProcess, hToken ;
    long                ret = -1 ;
    DWORD                s ;
    TOKEN_PRIVILEGES    tp, tpOld ;

    vi.dwOSVersionInfoSize = sizeof(vi) ;
    GetVersionEx(&vi) ;
    if ( vi.dwPlatformId == VER_PLATFORM_WIN32_NT )
    {
        // Der køres NT, og vi skal have lavet rettigheder til at lukke systemet ned
        if ( LookupPrivilegeValue(0,SE_SHUTDOWN_NAME,&luid) )
        {
            hProcess = GetCurrentProcess()  ;
            if ( hProcess )
            {
                if ( OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) )
                {
                    tp.PrivilegeCount = 1 ;
                    tp.Privileges->Attributes = SE_PRIVILEGE_ENABLED ;
                    tp.Privileges->Luid.HighPart = luid.HighPart ;
                    tp.Privileges->Luid.LowPart = luid.LowPart  ;
                    ret = AdjustTokenPrivileges(hToken, FALSE,&tp,sizeof(tp),&tpOld,&s) ;
                }
                CloseHandle(hToken) ;
            }
        }
    }

    if ( ExitWindowsEx(flag,0) )
        return true ;
    else
        return false ;
}

LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static long seconds = 0 ;
    char txt[80] = {0} ;
    static HDC hDC = GetDC(hWnd) ;
    static UINT uTimer = 0;
    size_t old_len = 0 ;

    RECT txtrect ;

    int xpos,
        ypos,
        hrs,
        mins,
        secs ;

    switch(message)
    {
    case WM_CREATE:            // her oprettes vinduet.

        uTimer = SetTimer(hWnd, 1, 1000, NULL);
        break;

    case WM_DESTROY:        // Afslut timer
        if(uTimer)
            KillTimer(hWnd, uTimer);

        PostQuitMessage(0);
        break;

    case WM_TIMER:

        seconds++ ;
        if ( seconds / 60 >= TTL_BEFORE_SHUTDOWN )
        {
            ShutDownSystem(EWX_POWEROFF) ;        // her lukkes systemet
        }

        secs = TTL_BEFORE_SHUTDOWN * 60 - seconds ;
        hrs = secs / 3600 ;                    // 3600 sekunder = én time.
        mins = ( secs - ( hrs * 3600 ) ) / 60 ;
        secs = ( secs - (( secs / 60 ) * 60 ) ) ;

        strcpy(txt,SZ_TXT) ;
        itoa(hrs,txt+strlen(txt),10) ;
        strcpy(txt+strlen(txt),SZ_HOURS) ;
        itoa(mins,txt+strlen(txt),10) ;
        strcpy(txt+strlen(txt),SZ_MINS) ;
        itoa(secs,txt+strlen(txt),10) ;
        strcpy(txt+strlen(txt),SZ_SECS) ;

        xpos = GetSystemMetrics(SM_CXSCREEN) / 2;
        ypos = GetSystemMetrics(SM_CYSCREEN) / 2;
        txtrect.bottom = ypos + 50 ;
        txtrect.top = ypos - 50 ;
        txtrect.right = xpos + 200 ;
        txtrect.left =  xpos - 200 ;

        if ( strlen(txt) < old_len  )
            FillRect(hDC,&txtrect,(HBRUSH)(COLOR_BACKGROUND+1)) ;
       
        old_len = strlen(txt) ;
        DrawText(hDC,txt,-1,&txtrect,DT_CENTER | DT_VCENTER) ;

        break ;



    default:
        return DefScreenSaverProc(hWnd, message, wParam, lParam);
    }

    return 0;
}

BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    return FALSE;        // returner false, vi vil ikke vise en konfigurer dialog.
}

BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
{
    return TRUE;
}

Jeg får stadig de 2 "expected" fejl
Avatar billede mr_wiseguy Nybegynder
24. september 2003 - 17:07 #22
Ok
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester